@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,108 @@
|
|
|
1
|
+
// Render-time formatting only; the JSON report keeps exact unrounded values.
|
|
2
|
+
// Rule: percent values use 2 decimals plus "%", correctness scores use 4 decimals, null is "unavailable".
|
|
3
|
+
export function formatContextWindowScalingPercent(value) {
|
|
4
|
+
return value === null ? "unavailable" : `${value.toFixed(2)}%`;
|
|
5
|
+
}
|
|
6
|
+
export function formatContextWindowScalingScore(value) {
|
|
7
|
+
return value === null ? "unavailable" : value.toFixed(4);
|
|
8
|
+
}
|
|
9
|
+
export function formatContextWindowScalingCount(value) {
|
|
10
|
+
return value === null ? "unavailable" : String(value);
|
|
11
|
+
}
|
|
12
|
+
function clean(value) {
|
|
13
|
+
return String(value).replace(/[\u0000-\u001f\u007f]/g, " ");
|
|
14
|
+
}
|
|
15
|
+
function row(parts) {
|
|
16
|
+
return `- ${parts.map(([label, value]) => `${label}: ${clean(value)}`).join(" | ")}`;
|
|
17
|
+
}
|
|
18
|
+
/** Lines for the "Context Window Scaling" section; every value comes from the report model. */
|
|
19
|
+
export function renderContextWindowScalingTextLines(section) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
lines.push(`Schema: ${clean(section.schemaVersion)}`);
|
|
22
|
+
lines.push(`Budgets (estimated context tokens): ${section.budgets.join(", ")}`);
|
|
23
|
+
lines.push(`Treatments: ${section.treatments.join(", ")}`);
|
|
24
|
+
lines.push(`Token Count Method: ${clean(section.tokenCountMethod ?? "unavailable")}`);
|
|
25
|
+
lines.push("Run Summary:");
|
|
26
|
+
const summary = section.runSummary;
|
|
27
|
+
for (const [label, value] of Object.entries(summary)) {
|
|
28
|
+
lines.push(`${label}: ${value}`);
|
|
29
|
+
}
|
|
30
|
+
lines.push("Budget Summary (one row per budget and treatment):");
|
|
31
|
+
for (const s of section.budgetTreatmentSummaries) {
|
|
32
|
+
lines.push(row([
|
|
33
|
+
["Budget", s.contextBudgetTokens],
|
|
34
|
+
["Treatment", s.variantId],
|
|
35
|
+
["Cells", s.totalCellCount],
|
|
36
|
+
["Fits", s.fitCount],
|
|
37
|
+
["Too Large", s.contextTooLargeCount],
|
|
38
|
+
["Context Unavailable", s.contextUnavailableCount],
|
|
39
|
+
["Success", s.successfulCellCount],
|
|
40
|
+
["Not Successful", s.notSuccessfulCellCount],
|
|
41
|
+
["Success Unavailable", s.successEvidenceUnavailableCount],
|
|
42
|
+
["Success Rate", formatContextWindowScalingPercent(s.successRatePercent)],
|
|
43
|
+
["Correctness Available", s.correctnessAvailableCount],
|
|
44
|
+
["Mean Correctness", formatContextWindowScalingScore(s.meanCorrectnessScore)],
|
|
45
|
+
["Mean Utilization", formatContextWindowScalingPercent(s.meanContextBudgetUtilizationPercent)],
|
|
46
|
+
["Min Utilization", formatContextWindowScalingPercent(s.minContextBudgetUtilizationPercent)],
|
|
47
|
+
["Max Utilization", formatContextWindowScalingPercent(s.maxContextBudgetUtilizationPercent)],
|
|
48
|
+
]));
|
|
49
|
+
}
|
|
50
|
+
lines.push("Case Context Evidence (one row per case and treatment; context does not vary by budget):");
|
|
51
|
+
for (const c of section.caseTreatmentContexts) {
|
|
52
|
+
lines.push(row([
|
|
53
|
+
["Case", c.caseId],
|
|
54
|
+
["Treatment", c.variantId],
|
|
55
|
+
["Context", c.contextStatus],
|
|
56
|
+
["Characters", formatContextWindowScalingCount(c.characterCount)],
|
|
57
|
+
["Estimated Tokens", formatContextWindowScalingCount(c.estimatedTokens)],
|
|
58
|
+
["Token Method", c.tokenCountMethod ?? "unavailable"],
|
|
59
|
+
["Observed Files", formatContextWindowScalingCount(c.observedFileCount)],
|
|
60
|
+
["Relevant File Evidence", c.relevantFileStatus],
|
|
61
|
+
["Expected Relevant Files", c.expectedRelevantFileCount],
|
|
62
|
+
["Observed Expected Files", formatContextWindowScalingCount(c.observedExpectedFileCount)],
|
|
63
|
+
["Omitted Relevant Files", formatContextWindowScalingCount(c.omittedRelevantFileCount)],
|
|
64
|
+
]));
|
|
65
|
+
}
|
|
66
|
+
lines.push("Omitted Relevant Files (benchmark-expected files not observed in the treatment context):");
|
|
67
|
+
lines.push(row([
|
|
68
|
+
["Evidence Available", section.relevantFileSummary.relevantFileEvidenceAvailableCount],
|
|
69
|
+
["Unavailable", section.relevantFileSummary.relevantFileEvidenceUnavailableCount],
|
|
70
|
+
["Not Applicable", section.relevantFileSummary.relevantFileEvidenceNotApplicableCount],
|
|
71
|
+
["Total Omitted", section.relevantFileSummary.totalOmittedRelevantFileCount],
|
|
72
|
+
]));
|
|
73
|
+
for (const c of section.caseTreatmentContexts) {
|
|
74
|
+
if (c.relevantFileStatus === "available" && (c.omittedRelevantFileCount ?? 0) > 0) {
|
|
75
|
+
const list = c.omittedRelevantFiles;
|
|
76
|
+
lines.push(`${clean(c.caseId)} / ${c.variantId}: omitted ${list.totalCount}; displayed ${list.displayedCount} of ${list.totalCount}; omitted from display ${list.omittedCount}; truncated ${list.truncated ? "yes" : "no"}`);
|
|
77
|
+
for (const file of list.items) {
|
|
78
|
+
lines.push(` - ${clean(file)}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (c.relevantFileStatus !== "available" && c.relevantFileReason) {
|
|
82
|
+
lines.push(`${clean(c.caseId)} / ${c.variantId}: ${c.relevantFileStatus} (${clean(c.relevantFileReason)})`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
lines.push("Per-Case Budget Matrix (one row per case, treatment, and budget):");
|
|
86
|
+
for (const cell of section.caseBudgetCells) {
|
|
87
|
+
lines.push(row([
|
|
88
|
+
["Case", cell.caseId],
|
|
89
|
+
["Treatment", cell.variantId],
|
|
90
|
+
["Budget", cell.contextBudgetTokens],
|
|
91
|
+
["Estimated Context Tokens", formatContextWindowScalingCount(cell.contextEstimatedTokens)],
|
|
92
|
+
["Fit", cell.contextFitStatus],
|
|
93
|
+
["Utilization", formatContextWindowScalingPercent(cell.contextBudgetUtilizationPercent)],
|
|
94
|
+
["Evaluation", cell.evaluationStatus],
|
|
95
|
+
["Correctness", cell.correctness.availability],
|
|
96
|
+
["Correctness Score", formatContextWindowScalingScore(cell.correctness.score)],
|
|
97
|
+
["Correctness Pass", cell.correctness.pass === null ? "unavailable" : cell.correctness.pass],
|
|
98
|
+
["Success Evidence", cell.successEvidence.status],
|
|
99
|
+
["Success", cell.successEvidence.success === null ? "unavailable" : cell.successEvidence.success],
|
|
100
|
+
["Success Reason", cell.successEvidence.reason],
|
|
101
|
+
]));
|
|
102
|
+
}
|
|
103
|
+
lines.push("Interpretation And Limitations:");
|
|
104
|
+
for (const item of section.interpretation) {
|
|
105
|
+
lines.push(`- ${clean(item)}`);
|
|
106
|
+
}
|
|
107
|
+
return lines;
|
|
108
|
+
}
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
// calculation beyond formatting an already-persisted number.
|
|
4
4
|
import { STALE_RISK_CLASSIFICATION_EXPLANATIONS } from "./buildIncrementalChangeStalenessReport.js";
|
|
5
5
|
import { REINDEX_RECOMMENDATION_EXPLANATIONS } from "./buildWarmIndexReuseReport.js";
|
|
6
|
+
import { isV2ReportSection } from "./buildIncrementalChangeStalenessReportV2.js";
|
|
7
|
+
import { renderIncrementalChangeStalenessHtmlV2 } from "./renderIncrementalChangeStalenessHtmlV2.js";
|
|
6
8
|
const MAX_DISPLAY_ITEMS = 20;
|
|
7
9
|
export function renderIncrementalChangeStalenessHtml(section) {
|
|
10
|
+
if (section !== null && isV2ReportSection(section))
|
|
11
|
+
return renderIncrementalChangeStalenessHtmlV2(section);
|
|
8
12
|
if (section === null) {
|
|
9
13
|
return `<section>
|
|
10
14
|
<h2>Incremental-Change And Staleness Evidence</h2>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// v0.6.3 -- V2 HTML section for the incremental-change-staleness plugin report. Renders the same persisted
|
|
2
|
+
// facts as the text renderer through the shared row builders; every persisted string is HTML-escaped.
|
|
3
|
+
import { COMPARISON_PRESENTATION_ORDER, EVIDENCE_FAMILY_NOTE, SCENARIO_SUMMARY_ROWS, TREATMENT_PRESENTATION_ORDER, affectedNeighborhoodSummary, comparisonBlock, treatmentBlock } from "./incrementalChangeStalenessReportRowsV2.js";
|
|
4
|
+
const MAX_DISPLAY_ITEMS = 20;
|
|
5
|
+
export function renderIncrementalChangeStalenessHtmlV2(section) {
|
|
6
|
+
return `<section>
|
|
7
|
+
<h2>Incremental-Change And Staleness Evidence</h2>
|
|
8
|
+
<p class="muted">Scoped experimental evidence: results are limited to the executed scenarios below. Full refresh is a comparison reference, not a declared best treatment.</p>
|
|
9
|
+
${table(["Field", "Value"], SCENARIO_SUMMARY_ROWS(section.summary))}
|
|
10
|
+
${section.scenarios.map(renderScenario).join("\n")}
|
|
11
|
+
<h3>Limitations</h3>
|
|
12
|
+
${list(section.limitations)}
|
|
13
|
+
</section>`;
|
|
14
|
+
}
|
|
15
|
+
function renderScenario(scenario) {
|
|
16
|
+
const lifecycle = scenario.lifecycle;
|
|
17
|
+
const affected = affectedNeighborhoodSummary(scenario);
|
|
18
|
+
return `<h3>Scenario: ${escapeHtml(scenario.scenarioId)}</h3>
|
|
19
|
+
<h4>Scenario Definition</h4>
|
|
20
|
+
${table(["Field", "Value"], [
|
|
21
|
+
["Scenario ID", scenario.scenarioId],
|
|
22
|
+
["Category", scenario.category],
|
|
23
|
+
["Benchmark project", scenario.benchmarkProjectId],
|
|
24
|
+
["Base case", scenario.baseCaseId],
|
|
25
|
+
["Answer policy", scenario.answerPolicy],
|
|
26
|
+
["Query", scenario.query ?? "unavailable"],
|
|
27
|
+
["Status", scenario.status],
|
|
28
|
+
["Failure reason", scenario.failureReason ?? "not applicable"]
|
|
29
|
+
])}
|
|
30
|
+
<p>Expected files:</p>
|
|
31
|
+
${boundedList(scenario.expectedFiles)}
|
|
32
|
+
<p>Expected symbols:</p>
|
|
33
|
+
${boundedList(scenario.expectedSymbols)}
|
|
34
|
+
<h4>Lifecycle Integrity</h4>
|
|
35
|
+
${lifecycle
|
|
36
|
+
? `${table(["Field", "Value"], [
|
|
37
|
+
["my-dev-kit version", lifecycle.myDevKitVersion ?? "unavailable"],
|
|
38
|
+
["Index invocations (total)", String(lifecycle.totalIndexInvocationCount)],
|
|
39
|
+
["Freshness assessments (total)", String(lifecycle.totalFreshnessAssessmentCount)],
|
|
40
|
+
...Object.entries(lifecycle.preMutationEquivalence).map(([id, result]) => [`Pre-mutation equivalence (${id} vs stale-index reference)`, result]),
|
|
41
|
+
...Object.entries(lifecycle.postMutationEquivalence).map(([id, result]) => [`Post-mutation equivalence (${id} vs stale-index reference)`, result])
|
|
42
|
+
])}<p>Controlled file paths:</p>${boundedList(lifecycle.controlledFilePaths)}<p>Source roots:</p>${boundedList(lifecycle.sourceRoots)}`
|
|
43
|
+
: "<p>Not available for this scenario.</p>"}
|
|
44
|
+
<h4>Affected-Neighborhood Evidence (Changed Baseline Neighborhood Relative To The Task)</h4>
|
|
45
|
+
${affected.state === "none"
|
|
46
|
+
? "<p>Not available.</p>"
|
|
47
|
+
: affected.state === "inconsistent"
|
|
48
|
+
? "<p>inconsistent persisted evidence</p>"
|
|
49
|
+
: `${table(["Field", "Value"], affected.rows)}<p>${escapeHtml(affected.explanation)}</p>`}
|
|
50
|
+
<p class="muted">${escapeHtml(EVIDENCE_FAMILY_NOTE)}</p>
|
|
51
|
+
${scenario.treatments.length === 0
|
|
52
|
+
? "<h4>Treatments</h4><p>Not produced: the scenario failed before any treatment evidence existed.</p>"
|
|
53
|
+
: TREATMENT_PRESENTATION_ORDER.map((entry) => renderTreatment(scenario, entry)).join("\n")}
|
|
54
|
+
<h4>Reference Comparisons (Against The Full-Refresh Reference)</h4>
|
|
55
|
+
${COMPARISON_PRESENTATION_ORDER.map((entry) => renderComparison(scenario, entry)).join("\n")}`;
|
|
56
|
+
}
|
|
57
|
+
function renderTreatment(scenario, entry) {
|
|
58
|
+
const block = treatmentBlock(scenario, entry.id, entry.label);
|
|
59
|
+
const title = `${block.label} Treatment (${entry.id})`;
|
|
60
|
+
if (!block.available)
|
|
61
|
+
return `<h4>${escapeHtml(title)}</h4><p>Not available.</p>`;
|
|
62
|
+
return `<h4>${escapeHtml(title)}</h4>
|
|
63
|
+
${table(["Field", "Value"], block.rows)}
|
|
64
|
+
<p><strong>Refresh Execution</strong> (upstream evidence of what my-dev-kit actually did)</p>
|
|
65
|
+
${table(["Field", "Value"], block.refreshRows)}
|
|
66
|
+
${block.fallbackStatement ? `<p class="fallback"><strong>${escapeHtml(block.fallbackStatement)}</strong></p>` : ""}
|
|
67
|
+
${block.forcedNeighborSample ? `<p>Forced-neighbor sample:</p>${boundedList(block.forcedNeighborSample)}` : ""}
|
|
68
|
+
<p>Files read:</p>
|
|
69
|
+
${boundedList(block.filesRead)}
|
|
70
|
+
<p>Required files:</p>
|
|
71
|
+
${boundedList(block.requiredFiles)}
|
|
72
|
+
<p>Observed files:</p>
|
|
73
|
+
${boundedList(block.observedFiles)}
|
|
74
|
+
<p>Missing files:</p>
|
|
75
|
+
${boundedList(block.missingFiles)}`;
|
|
76
|
+
}
|
|
77
|
+
function renderComparison(scenario, entry) {
|
|
78
|
+
const block = comparisonBlock(scenario, entry);
|
|
79
|
+
if (!block.available)
|
|
80
|
+
return `<h5>${escapeHtml(block.label)}</h5><p>Not available.</p>`;
|
|
81
|
+
return `<h5>${escapeHtml(block.label)}</h5>
|
|
82
|
+
${table(["Field", "Value"], block.rows)}
|
|
83
|
+
<p>Reason codes:</p>
|
|
84
|
+
${list(block.reasonCodes)}
|
|
85
|
+
<p>${escapeHtml(block.explanation)}</p>`;
|
|
86
|
+
}
|
|
87
|
+
function boundedList(items) {
|
|
88
|
+
if (items.length === 0)
|
|
89
|
+
return "<p>none</p>";
|
|
90
|
+
const shown = items.slice(0, MAX_DISPLAY_ITEMS);
|
|
91
|
+
const omitted = items.length - shown.length;
|
|
92
|
+
return `${list(shown)}${omitted > 0 ? `<p class="muted">... ${omitted} more</p>` : ""}`;
|
|
93
|
+
}
|
|
94
|
+
function list(items) {
|
|
95
|
+
if (items.length === 0)
|
|
96
|
+
return "<ul><li>none</li></ul>";
|
|
97
|
+
return `<ul>${items.map((item) => `<li>${escapeHtml(item)}</li>`).join("")}</ul>`;
|
|
98
|
+
}
|
|
99
|
+
function table(headers, rows) {
|
|
100
|
+
return `<table><thead><tr>${headers.map((header) => `<th>${escapeHtml(header)}</th>`).join("")}</tr></thead><tbody>${rows
|
|
101
|
+
.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).join("")}</tr>`)
|
|
102
|
+
.join("")}</tbody></table>`;
|
|
103
|
+
}
|
|
104
|
+
function escapeHtml(value) {
|
|
105
|
+
return String(value ?? "")
|
|
106
|
+
.replaceAll("&", "&")
|
|
107
|
+
.replaceAll("<", "<")
|
|
108
|
+
.replaceAll(">", ">")
|
|
109
|
+
.replaceAll('"', """)
|
|
110
|
+
.replaceAll("'", "'");
|
|
111
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// v0.6.3 -- V2 text section for the incremental-change-staleness plugin report. Renders only persisted
|
|
2
|
+
// V2 report-model fields (via the shared row builders); no recomputation. Lists are bounded.
|
|
3
|
+
import { COMPARISON_PRESENTATION_ORDER, EVIDENCE_FAMILY_NOTE, SCENARIO_SUMMARY_ROWS, TREATMENT_PRESENTATION_ORDER, affectedNeighborhoodSummary, comparisonBlock, treatmentBlock } from "./incrementalChangeStalenessReportRowsV2.js";
|
|
4
|
+
function renderScenario(lines, scenario, h) {
|
|
5
|
+
h.pushSection(lines, `Scenario: ${scenario.scenarioId}`);
|
|
6
|
+
lines.push(h.fieldLine("Category", scenario.category));
|
|
7
|
+
lines.push(h.fieldLine("Status", scenario.status));
|
|
8
|
+
lines.push(h.fieldLine("Failure Reason", scenario.failureReason));
|
|
9
|
+
lines.push(h.fieldLine("Benchmark Project", scenario.benchmarkProjectId));
|
|
10
|
+
lines.push(h.fieldLine("Base Case", scenario.baseCaseId));
|
|
11
|
+
lines.push(h.fieldLine("Answer Policy", scenario.answerPolicy));
|
|
12
|
+
lines.push(h.fieldLine("Query", scenario.query));
|
|
13
|
+
h.pushBoundedStringList(lines, "Expected Files", scenario.expectedFiles);
|
|
14
|
+
h.pushBoundedStringList(lines, "Expected Symbols", scenario.expectedSymbols);
|
|
15
|
+
h.pushSection(lines, "Lifecycle");
|
|
16
|
+
const lifecycle = scenario.lifecycle;
|
|
17
|
+
if (!lifecycle) {
|
|
18
|
+
lines.push("Not available.");
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
lines.push(h.fieldLine("my-dev-kit Version", lifecycle.myDevKitVersion));
|
|
22
|
+
lines.push(h.fieldLine("Index Invocations (total)", lifecycle.totalIndexInvocationCount));
|
|
23
|
+
lines.push(h.fieldLine("Freshness Assessments (total)", lifecycle.totalFreshnessAssessmentCount));
|
|
24
|
+
for (const [treatmentId, result] of Object.entries(lifecycle.preMutationEquivalence)) {
|
|
25
|
+
lines.push(h.fieldLine(`Pre-Mutation Equivalence (${treatmentId} vs stale-index reference)`, result));
|
|
26
|
+
}
|
|
27
|
+
for (const [treatmentId, result] of Object.entries(lifecycle.postMutationEquivalence)) {
|
|
28
|
+
lines.push(h.fieldLine(`Post-Mutation Equivalence (${treatmentId} vs stale-index reference)`, result));
|
|
29
|
+
}
|
|
30
|
+
h.pushBoundedStringList(lines, "Controlled File Paths", lifecycle.controlledFilePaths);
|
|
31
|
+
h.pushBoundedStringList(lines, "Source Roots", lifecycle.sourceRoots);
|
|
32
|
+
}
|
|
33
|
+
h.pushSection(lines, "Affected-Neighborhood Evidence (changed baseline neighborhood relative to the task)");
|
|
34
|
+
const affected = affectedNeighborhoodSummary(scenario);
|
|
35
|
+
if (affected.state === "none") {
|
|
36
|
+
lines.push("Not available.");
|
|
37
|
+
}
|
|
38
|
+
else if (affected.state === "inconsistent") {
|
|
39
|
+
lines.push("inconsistent persisted evidence");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
for (const [label, value] of affected.rows)
|
|
43
|
+
lines.push(h.fieldLine(label, value));
|
|
44
|
+
lines.push(h.fieldLine("Reindex Recommendation Explanation", affected.explanation));
|
|
45
|
+
}
|
|
46
|
+
lines.push(EVIDENCE_FAMILY_NOTE);
|
|
47
|
+
if (scenario.treatments.length === 0) {
|
|
48
|
+
h.pushSection(lines, "Treatments");
|
|
49
|
+
lines.push("Not produced: the scenario failed before any treatment evidence existed.");
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
for (const entry of TREATMENT_PRESENTATION_ORDER) {
|
|
53
|
+
const block = treatmentBlock(scenario, entry.id, entry.label);
|
|
54
|
+
h.pushSection(lines, `${block.label} Treatment (${entry.id})`);
|
|
55
|
+
if (!block.available) {
|
|
56
|
+
lines.push("Not available.");
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
for (const [label, value] of block.rows)
|
|
60
|
+
lines.push(h.fieldLine(label, value));
|
|
61
|
+
lines.push("Refresh Execution (upstream evidence of what my-dev-kit actually did):");
|
|
62
|
+
for (const [label, value] of block.refreshRows)
|
|
63
|
+
lines.push(h.fieldLine(label, value));
|
|
64
|
+
if (block.fallbackStatement)
|
|
65
|
+
lines.push(block.fallbackStatement);
|
|
66
|
+
if (block.forcedNeighborSample)
|
|
67
|
+
h.pushBoundedStringList(lines, "Forced-Neighbor Sample", block.forcedNeighborSample);
|
|
68
|
+
h.pushBoundedStringList(lines, "Files Read", block.filesRead);
|
|
69
|
+
h.pushBoundedStringList(lines, "Required Files", block.requiredFiles);
|
|
70
|
+
h.pushBoundedStringList(lines, "Observed Files", block.observedFiles);
|
|
71
|
+
h.pushBoundedStringList(lines, "Missing Files", block.missingFiles);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
h.pushSection(lines, "Reference Comparisons (against the full-refresh reference)");
|
|
75
|
+
for (const entry of COMPARISON_PRESENTATION_ORDER) {
|
|
76
|
+
const block = comparisonBlock(scenario, entry);
|
|
77
|
+
lines.push(block.label);
|
|
78
|
+
if (!block.available) {
|
|
79
|
+
lines.push("Not available.");
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
for (const [label, value] of block.rows)
|
|
83
|
+
lines.push(h.fieldLine(label, value));
|
|
84
|
+
h.pushDashList(lines, block.reasonCodes);
|
|
85
|
+
lines.push(block.explanation);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function renderIncrementalChangeStalenessSectionV2(lines, section, h) {
|
|
89
|
+
h.pushSection(lines, "Summary");
|
|
90
|
+
for (const [label, value] of SCENARIO_SUMMARY_ROWS(section.summary))
|
|
91
|
+
lines.push(h.fieldLine(label, value));
|
|
92
|
+
for (const scenario of section.scenarios)
|
|
93
|
+
renderScenario(lines, scenario, h);
|
|
94
|
+
h.pushSection(lines, "Limitations");
|
|
95
|
+
h.pushDashList(lines, section.limitations);
|
|
96
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { renderContextStrategyComparisonV043Html } from "./renderContextStrategyComparisonV043Html.js";
|
|
2
2
|
import { renderWarmIndexReuseHtml } from "./renderWarmIndexReuseHtml.js";
|
|
3
3
|
import { renderIncrementalChangeStalenessHtml } from "./renderIncrementalChangeStalenessHtml.js";
|
|
4
|
+
import { renderContextWindowScalingHtml } from "./renderContextWindowScalingHtml.js";
|
|
4
5
|
export function renderPluginExperimentReportHtml(report) {
|
|
5
6
|
return `<!DOCTYPE html>
|
|
6
7
|
<html lang="en">
|
|
@@ -102,6 +103,8 @@ export function renderPluginExperimentReportHtml(report) {
|
|
|
102
103
|
|
|
103
104
|
${renderIncrementalChangeStalenessHtml(report.incrementalChangeStaleness)}
|
|
104
105
|
|
|
106
|
+
${renderContextWindowScalingHtml(report.contextWindowScaling)}
|
|
107
|
+
|
|
105
108
|
<section>
|
|
106
109
|
<h2>Warnings, Skips, And Failures</h2>
|
|
107
110
|
${report.findings.length ? table(["Severity", "Code", "Message", "Variant", "Case"], report.findings.map((finding) => [
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { STALE_RISK_CLASSIFICATION_EXPLANATIONS } from "./buildIncrementalChangeStalenessReport.js";
|
|
2
|
+
import { isV2ReportSection } from "./buildIncrementalChangeStalenessReportV2.js";
|
|
3
|
+
import { renderIncrementalChangeStalenessSectionV2 } from "./renderIncrementalChangeStalenessTextV2.js";
|
|
2
4
|
import { REINDEX_RECOMMENDATION_EXPLANATIONS } from "./buildWarmIndexReuseReport.js";
|
|
5
|
+
import { renderContextWindowScalingTextLines } from "./renderContextWindowScalingText.js";
|
|
3
6
|
function sanitizeScalar(value) {
|
|
4
7
|
const text = String(value);
|
|
5
8
|
let result = "";
|
|
@@ -612,6 +615,10 @@ function renderIncrementalChangeStalenessSection(lines, section) {
|
|
|
612
615
|
lines.push("Not applicable to this plugin.");
|
|
613
616
|
return;
|
|
614
617
|
}
|
|
618
|
+
if (isV2ReportSection(section)) {
|
|
619
|
+
renderIncrementalChangeStalenessSectionV2(lines, section, { pushSection, fieldLine, pushDashList, pushBoundedStringList });
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
615
622
|
pushSection(lines, "Summary");
|
|
616
623
|
lines.push(fieldLine("Scenarios", section.scenarioCount));
|
|
617
624
|
lines.push(fieldLine("Ready", section.readyScenarioCount));
|
|
@@ -657,6 +664,13 @@ export function renderPluginExperimentReportText(report) {
|
|
|
657
664
|
renderWarmIndexReuseSection(lines, report.warmIndexReuse);
|
|
658
665
|
pushSection(lines, "Incremental-Change And Staleness Evidence");
|
|
659
666
|
renderIncrementalChangeStalenessSection(lines, report.incrementalChangeStaleness);
|
|
667
|
+
pushSection(lines, "Context Window Scaling");
|
|
668
|
+
if (report.contextWindowScaling === null) {
|
|
669
|
+
lines.push("Not applicable to this plugin.");
|
|
670
|
+
}
|
|
671
|
+
else {
|
|
672
|
+
lines.push(...renderContextWindowScalingTextLines(report.contextWindowScaling));
|
|
673
|
+
}
|
|
660
674
|
pushSection(lines, "Warnings, Skips, And Failures");
|
|
661
675
|
pushDashList(lines, report.findings.map((finding) => `${finding.severity} ${finding.code} ${finding.message} variant=${finding.variantId ?? ""} case=${finding.caseId ?? ""}`));
|
|
662
676
|
pushSection(lines, "Artifacts");
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { runSecurityCommand } from "../commandRunner.js";
|
|
2
2
|
import { resolveCommand } from "../../core/resolveCommand.js";
|
|
3
3
|
import { skippedCheck } from "../cliAdversarial/runAdversarialCheck.js";
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// This local check only verifies CodeQL CLI availability and integration.
|
|
5
|
+
// Full CodeQL analysis is owned by .github/workflows/codeql.yml.
|
|
6
|
+
// Release readiness requires successful GitHub analysis for the exact candidate SHA.
|
|
7
7
|
export async function runCodeqlCheck(options) {
|
|
8
8
|
const { cwd, timeoutMs } = options;
|
|
9
9
|
const resolved = resolveCommand("codeql", { cwd, env: process.env });
|
|
10
10
|
if (resolved.resolutionKind === "unavailable") {
|
|
11
11
|
return skippedCheck({
|
|
12
12
|
id: "codeql-scan",
|
|
13
|
-
name: "CodeQL
|
|
13
|
+
name: "CodeQL CLI availability preflight",
|
|
14
14
|
category: "static-scan",
|
|
15
|
-
reason: "CodeQL CLI
|
|
15
|
+
reason: "Local CodeQL CLI is unavailable, so the local availability preflight is skipped. Full release-readiness coverage requires a successful GitHub CodeQL advanced-setup analysis for the exact candidate SHA.",
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
const startedAt = new Date().toISOString();
|
|
@@ -29,7 +29,7 @@ export async function runCodeqlCheck(options) {
|
|
|
29
29
|
if (versionCmd.exitCode !== 0 || versionCmd.exitCode === null) {
|
|
30
30
|
return {
|
|
31
31
|
id: "codeql-scan",
|
|
32
|
-
name: "CodeQL
|
|
32
|
+
name: "CodeQL CLI availability preflight",
|
|
33
33
|
category: "static-scan",
|
|
34
34
|
status: "failed",
|
|
35
35
|
severity: "major",
|
|
@@ -50,10 +50,10 @@ export async function runCodeqlCheck(options) {
|
|
|
50
50
|
command: "codeql version --format terse",
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
// CLI is present and functional
|
|
53
|
+
// The CLI is present and functional; this is not repository-wide analysis.
|
|
54
54
|
return {
|
|
55
55
|
id: "codeql-scan",
|
|
56
|
-
name: "CodeQL
|
|
56
|
+
name: "CodeQL CLI availability preflight",
|
|
57
57
|
category: "static-scan",
|
|
58
58
|
status: "passed",
|
|
59
59
|
severity: "informational",
|
package/docs/METRICS.md
CHANGED
|
@@ -596,6 +596,32 @@ All six metrics are warm-side only (they are not on the raw-full-file side, beca
|
|
|
596
596
|
|
|
597
597
|
**Observational only.** The evidence never triggers reindexing, suppresses or alters warm retrieval, or changes execution, provider, agent, correctness, or token-evidence status. It uses only the baseline graph of the prepared index: there is no graph-diff, refreshed-index, or stale-versus-refreshed comparison.
|
|
598
598
|
|
|
599
|
+
## Context-window scaling evidence (v0.7.0)
|
|
600
|
+
|
|
601
|
+
Status: **released in v0.7.0**. The `context-window-scaling` plugin compares `raw-full-file` and `my-dev-kit-guided` treatment contexts against selected estimated-token budgets. It runs the bundled case catalog against the fixed self target.
|
|
602
|
+
|
|
603
|
+
### Measurement and budget-cell semantics
|
|
604
|
+
|
|
605
|
+
- **Estimated tokens:** context construction records character count and an estimated token count using the Lab's deterministic `ceil(characters / 4)` heuristic. It is not a provider tokenizer result, model-window measurement, or billing telemetry.
|
|
606
|
+
- **Budget values:** defaults are 8192, 16384, 32768, and 65536 tokens (shown as 8k, 16k, 32k, and 64k). Users can select other positive safe integers. Duplicate values after normalization are rejected; accepted budgets are sorted ascending.
|
|
607
|
+
- **Context fit:** `fits` when estimated context tokens are less than or equal to the selected budget; `context-too-large` when they exceed it; `unavailable` when context measurement is unavailable. This classification does not truncate or reconstruct the context. Each treatment's context is built once, independent of its budgets.
|
|
608
|
+
- **Budget utilization:** `contextBudgetUtilizationPercent = estimatedContextTokens / budget * 100`. It is not capped at 100 percent, so an over-budget context can have utilization greater than 100. It is unavailable when context size is unavailable.
|
|
609
|
+
- **Correctness:** the existing deterministic fake-agent answer-key evaluator runs no more than once per treatment and is shared by every budget cell where that treatment's context fits. Correctness is unavailable for a `context-too-large` cell and is not converted to zero. This harness's evaluation is context-independent; it does not estimate how a real model's correctness would change with the supplied context.
|
|
610
|
+
- **Success:** success is true only when the context fits and the available correctness evidence passes. A too-large context is an available unsuccessful cell with reason `context-too-large`, even though no evaluation ran. Operational or evidence-unavailable cells remain unavailable and are excluded from success-rate denominators. Thus context-too-large cells count as not successful, while unavailable cells do not.
|
|
611
|
+
- **Omitted relevant files:** benchmark-expected relevant files absent from the treatment's observed context provenance. This is an evidence count/list, not retrieval precision, recall, or an irrelevant-context ratio. The report bounds displayed omitted paths and retains total/displayed/omitted counts.
|
|
612
|
+
|
|
613
|
+
### Aggregate and per-cell metrics
|
|
614
|
+
|
|
615
|
+
`aggregateContextWindowScaling` in `src/experiments/plugins/contextWindowScaling/metrics.ts` owns the per-budget and run summaries. `buildContextWindowScalingReport.ts` presents these results without recalculating fit, utilization, success, or correctness.
|
|
616
|
+
|
|
617
|
+
For each budget and treatment, aggregate evidence includes `fitCount`, `contextTooLargeCount`, `contextUnavailableCount`, `successfulCellCount`, `notSuccessfulCellCount`, success-evidence availability counts, `successRatePercent`, correctness availability counts and `meanCorrectnessScore`, and availability counts plus mean/min/max context-budget utilization. Success rate is successful cells divided by success-evidence-available cells; it is null when none are available. Mean correctness averages only available scores and is null when none are available. Utilization summaries include only measured values and remain uncapped.
|
|
618
|
+
|
|
619
|
+
The generic `ExperimentMetric` projection emits run-level case and budget counts, plus per-budget/per-treatment fit count, too-large count, successful count, success rate, mean correctness, and mean utilization. Per-case treatment outcomes carry context estimated tokens, omitted relevant file count when available, and budget-scoped utilization, correctness score, and success evidence. Unavailable values remain null/unavailable with their evidence status; no value is fabricated as zero.
|
|
620
|
+
|
|
621
|
+
The report artifact schema is `my-dev-kit-lab-context-window-scaling-report-v1`. It includes run summaries, budget-treatment summaries, per-treatment context measurements, budget cells, relevant-file summary, and fixed interpretation limits. The execution artifact is `context-window-scaling-execution.json` (`my-dev-kit-lab-context-window-scaling-execution-v1`) and does not embed context text.
|
|
622
|
+
|
|
623
|
+
There is no composite score, winner, or ranking. Budgets are experiment thresholds, not assertions about actual provider context-window capacities. See [COMMANDS.md](COMMANDS.md), [WORKFLOWS.md](WORKFLOWS.md), and [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
624
|
+
|
|
599
625
|
## Incremental-change and staleness evidence (v0.6.2)
|
|
600
626
|
|
|
601
627
|
The `incremental-change-staleness` plugin reuses the six existing v0.6.1 affected-neighborhood numeric metrics unchanged (`changedFileCount`, `changedSymbolCount`, `affectedNodeCount`, `affectedEdgeCount`, `taskOverlapCount`, `taskOverlapPercent`; see "Affected-neighborhood metrics (v0.6.1)" above) and adds no new numeric formula.
|
|
@@ -629,3 +655,35 @@ The `incremental-change-staleness` plugin reuses the six existing v0.6.1 affecte
|
|
|
629
655
|
`staleRiskClassification` is not a numeric risk score, not a winner, not a ranking, and not an automatic reindex decision. `no-observed-stale-regression` means only that this matched scenario did not observe a stale-specific regression under these two frozen evidence dimensions; it does not establish that stale indexes are generally safe. `reindexRecommendation` (the released v0.6.1 categorical evidence) remains separate observational evidence about the affected-neighborhood analysis; it does not select or trigger either treatment and is not an input to the stale-risk classification above.
|
|
630
656
|
|
|
631
657
|
**Report presentation.** `report.incrementalChangeStaleness` holds `scenarioCount`, `readyScenarioCount`, `failedScenarioCount`, `observedStaleRegressionCount`, `noObservedStaleRegressionCount`, `inconclusiveCount`, per-scenario evidence (lifecycle, both treatments in order, and the comparison), and fixed limitations text. There is no overall score, grade, winner, best-treatment, or safe-to-skip-reindex field anywhere in the report or the persisted execution artifact.
|
|
658
|
+
|
|
659
|
+
### Partial-refresh treatment evidence (v0.6.3, retained in current release)
|
|
660
|
+
|
|
661
|
+
The `incremental-change-staleness` plugin now compares four treatments (`stale-index`, `changed-files-refresh`, `affected-neighborhood-refresh`, `full-refresh`). It defines no new formula. Two evidence families must not be merged:
|
|
662
|
+
|
|
663
|
+
- **Lab task-relationship affected-neighborhood evidence** (released v0.6.1, unchanged): the six numeric metrics `changedFileCount`, `changedSymbolCount`, `affectedNodeCount`, `affectedEdgeCount`, `taskOverlapCount`, `taskOverlapPercent`, plus the categorical `relationship` and `reindexRecommendation`. They describe the baseline graph neighborhood of the controlled change relative to the task. `changedSymbolCount` still means baseline symbol identities belonging to confirmed changed indexed files, not proof that any symbol body changed, and `reindexRecommendation` stays observational: it selects and executes no treatment.
|
|
664
|
+
- **Upstream refresh execution evidence** (new): what my-dev-kit actually did during a partial refresh invocation. It does not depend on the task and is not a task-relevance measure.
|
|
665
|
+
|
|
666
|
+
**Numeric upstream-refresh metrics** (unit `count`; emitted as `ExperimentMetric` entries on the outcome of an incremental treatment, `changed-files-refresh` or `affected-neighborhood-refresh`, and never on `stale-index` or `full-refresh`):
|
|
667
|
+
|
|
668
|
+
| Metric ID | Meaning |
|
|
669
|
+
|---|---|
|
|
670
|
+
| `upstream-refresh-fresh-extraction-file-count` | Files upstream freshly re-extracted during the refresh invocation. |
|
|
671
|
+
| `upstream-refresh-reused-file-count` | Files upstream reused from the previous index. |
|
|
672
|
+
| `upstream-refresh-forced-neighbor-reanalysis-file-count` | Neighboring files upstream forced to re-analyze during the refresh. |
|
|
673
|
+
| `upstream-refresh-seed-file-count` | Seed files upstream selected for the affected-neighborhood refresh. |
|
|
674
|
+
| `upstream-refresh-seed-symbol-count` | Seed symbols upstream selected. |
|
|
675
|
+
| `upstream-refresh-affected-node-count` | Graph nodes upstream treated as affected. |
|
|
676
|
+
| `upstream-refresh-affected-edge-count` | Graph edges upstream treated as affected. |
|
|
677
|
+
|
|
678
|
+
Availability: the first three are always present for a validated incremental treatment. The seed, node, and edge counts appear only when upstream supplied a non-null value; a `null` upstream value is unavailable evidence and the metric is omitted, never emitted as zero. These counts describe upstream execution only: they do not prove a treatment is better, faster, safer, or more accurate, and they are distinct from the Lab `affectedNodeCount`/`affectedEdgeCount` above (different metric IDs).
|
|
679
|
+
|
|
680
|
+
**Categorical refresh evidence** (not numeric metrics, never converted to numbers): `requestedScope` (`changed-files` or `affected-neighborhood`), `appliedScope` (the scope upstream actually applied: `changed-files`, `affected-neighborhood`, `full`, or `none`), `selectionStatus` (`applied`, `fallback-full`, or `not-needed`), `fallbackReason` (an upstream reason or `null`), `forcedNeighborSample` (a bounded sample of path strings, capped by upstream, so its length can be less than the forced-neighbor count), and the Lab `refreshRealization` (`NO_REFRESH`, `APPLIED_PARTIAL`, `FALLBACK_FULL`, `FULL_REFRESH`). Only `changed-files-refresh` and `affected-neighborhood-refresh` can be `APPLIED_PARTIAL` or `FALLBACK_FULL`.
|
|
681
|
+
|
|
682
|
+
**Reference comparisons** (exactly three per ready scenario, each against `full-refresh`):
|
|
683
|
+
|
|
684
|
+
- `stale-index` vs `full-refresh` uses the v0.6.2 stale-risk vocabulary and precedence unchanged (`observed-stale-regression`, `no-observed-stale-regression`, `inconclusive`).
|
|
685
|
+
- `changed-files-refresh` vs `full-refresh` and `affected-neighborhood-refresh` vs `full-refresh` use neutral candidate relations (`candidate-worse`, `same`, `candidate-better`, `unknown`) for deterministic fake-agent correctness and for the required-file status, with the frozen precedence: (1) `not-comparable-as-partial-refresh` if the candidate fell back to a full rebuild (`FALLBACK_FULL`); (2) `observed-regression-relative-to-full` if correctness or required-file presence is `candidate-worse`; (3) `inconclusive` if either relation is `unknown`; (4) otherwise `no-observed-regression-relative-to-full`.
|
|
686
|
+
|
|
687
|
+
`no-observed-regression-relative-to-full` means only that the executed scenario showed no regression under those two evidence dimensions. It does not establish equivalence or safety and does not show that full refresh is unnecessary. `not-comparable-as-partial-refresh` says the run gives no evidence about the requested partial behavior. There is no winner, ranking, composite score, safety score, safe-to-skip-refresh flag, or stale-risk percentage. Ordinary per-treatment correctness `score` remains the existing deterministic fake-agent evidence.
|
|
688
|
+
|
|
689
|
+
**Report presentation.** `report.incrementalChangeStaleness` (schema `my-dev-kit-lab-incremental-change-staleness-report-v2`) holds the summary counts (including per-treatment applied-partial, fallback, and classification counts), per-scenario lifecycle, four treatments and three comparisons identified by explicit treatment IDs, and fixed limitations text. Unavailable evidence is written as `unavailable` or `not applicable`, never zero. Historical V1 reports keep their original two-treatment presentation.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
|
|
5
|
-
const sourceRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
const targetRoot = process.argv[2];
|
|
7
|
-
if (!targetRoot) {
|
|
8
|
-
console.error("prepare requires a target root argument");
|
|
9
|
-
process.exit(2);
|
|
10
|
-
}
|
|
11
|
-
fs.mkdirSync(path.join(targetRoot, "app"), { recursive: true });
|
|
12
|
-
fs.mkdirSync(path.join(targetRoot, "out"), { recursive: true });
|
|
13
|
-
for (const file of ["index.html", "server.mjs"]) fs.copyFileSync(path.join(sourceRoot, file), path.join(targetRoot, "app", file));
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const sourceRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const targetRoot = process.argv[2];
|
|
7
|
+
if (!targetRoot) {
|
|
8
|
+
console.error("prepare requires a target root argument");
|
|
9
|
+
process.exit(2);
|
|
10
|
+
}
|
|
11
|
+
fs.mkdirSync(path.join(targetRoot, "app"), { recursive: true });
|
|
12
|
+
fs.mkdirSync(path.join(targetRoot, "out"), { recursive: true });
|
|
13
|
+
for (const file of ["index.html", "server.mjs"]) fs.copyFileSync(path.join(sourceRoot, file), path.join(targetRoot, "app", file));
|
|
14
14
|
fs.writeFileSync(path.join(targetRoot, "out", "report.json"), JSON.stringify({ prepared: true, counts: { widgets: 3 } }, null, 2), "utf8");
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import http from "node:http";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const port = Number(process.env.TUTORIAL_FIXTURE_PORT || 0);
|
|
8
|
-
const server = http.createServer((req, res) => {
|
|
9
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
10
|
-
if (url.pathname === "/api/status") { res.writeHead(200, { "content-type": "application/json" }); res.end(JSON.stringify({ ok: true, widgets: 3 })); return; }
|
|
11
|
-
const filePath = url.pathname === "/" ? path.join(root, "index.html") : path.join(root, url.pathname);
|
|
12
|
-
fs.readFile(filePath, (error, contents) => { if (error) { res.writeHead(404); res.end("not found"); return; } res.writeHead(200, { "content-type": filePath.endsWith(".html") ? "text/html" : "application/octet-stream" }); res.end(contents); });
|
|
13
|
-
});
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const port = Number(process.env.TUTORIAL_FIXTURE_PORT || 0);
|
|
8
|
+
const server = http.createServer((req, res) => {
|
|
9
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
10
|
+
if (url.pathname === "/api/status") { res.writeHead(200, { "content-type": "application/json" }); res.end(JSON.stringify({ ok: true, widgets: 3 })); return; }
|
|
11
|
+
const filePath = url.pathname === "/" ? path.join(root, "index.html") : path.join(root, url.pathname);
|
|
12
|
+
fs.readFile(filePath, (error, contents) => { if (error) { res.writeHead(404); res.end("not found"); return; } res.writeHead(200, { "content-type": filePath.endsWith(".html") ? "text/html" : "application/octet-stream" }); res.end(contents); });
|
|
13
|
+
});
|
|
14
14
|
server.listen(port, "127.0.0.1", () => console.log("tutorial fixture listening on " + server.address().port));
|