@dailephd/my-dev-kit-lab 0.4.2 → 0.4.3
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/README.md +23 -113
- package/benchmarks/contracts/todo-behavior.md +1 -1
- package/benchmarks/projects/task-analytics-large-mixed/README.md +2 -0
- package/benchmarks/projects/task-workflow-medium-ts/README.md +3 -1
- package/dist/src/evaluation/stageContextDeterminism/calculateStageContextDeterminism.js +52 -0
- package/dist/src/evaluation/stageContextDeterminism/canonicalizeStageContextRun.js +53 -0
- package/dist/src/evaluation/stageContextDeterminism/index.js +2 -0
- package/dist/src/evaluation/stageContextDeterminism/types.js +1 -0
- package/dist/src/evaluation/stageContextExpectations/index.js +2 -0
- package/dist/src/evaluation/stageContextExpectations/readStageContextExpectationFixtureV1.js +50 -0
- package/dist/src/evaluation/stageContextExpectations/readTypes.js +1 -0
- package/dist/src/evaluation/stageContextExpectations/types.js +1 -0
- package/dist/src/evaluation/stageContextExpectations/validation.js +568 -0
- package/dist/src/evaluation/stageContextMetrics/calculateArtifactStateMetrics.js +130 -0
- package/dist/src/evaluation/stageContextMetrics/calculateContextSizeMetrics.js +85 -0
- package/dist/src/evaluation/stageContextMetrics/calculateExpectationMetrics.js +103 -0
- package/dist/src/evaluation/stageContextMetrics/calculateResponsibilityMappingMetrics.js +36 -0
- package/dist/src/evaluation/stageContextMetrics/collectContextCapsuleEvidence.js +312 -0
- package/dist/src/evaluation/stageContextMetrics/collectRetrievalAuditEvidence.js +35 -0
- package/dist/src/evaluation/stageContextMetrics/collectWorkflowInstructionEvidence.js +137 -0
- package/dist/src/evaluation/stageContextMetrics/evaluateV043StageContextExecution.js +247 -0
- package/dist/src/evaluation/stageContextMetrics/index.js +10 -0
- package/dist/src/evaluation/stageContextMetrics/matchStageContextExpectations.js +38 -0
- package/dist/src/evaluation/stageContextMetrics/targetKeys.js +35 -0
- package/dist/src/evaluation/stageContextMetrics/types.js +1 -0
- package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +79 -0
- package/dist/src/evaluation/stageContextSelectors/contextCapsuleSelectors.js +126 -0
- package/dist/src/evaluation/stageContextSelectors/index.js +4 -0
- package/dist/src/evaluation/stageContextSelectors/retrievalAuditRecordSelectors.js +54 -0
- package/dist/src/evaluation/stageContextSelectors/workflowInstructionPacketSelectors.js +51 -0
- package/dist/src/evaluation/targetImmutability/captureTargetSnapshot.js +208 -0
- package/dist/src/evaluation/targetImmutability/compareTargetSnapshots.js +56 -0
- package/dist/src/evaluation/targetImmutability/index.js +3 -0
- package/dist/src/evaluation/targetImmutability/types.js +1 -0
- package/dist/src/evaluation/targetImmutability/validateTargetImmutabilityConfig.js +130 -0
- package/dist/src/evaluation/upstreamArtifacts/artifactReadTypes.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/index.js +3 -0
- package/dist/src/evaluation/upstreamArtifacts/jsonTypes.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/myDevKitClassificationTypesV1.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/myDevKitContextArtifactsV1.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/myDevKitSemanticTypesV1.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/orchestratorWorkflowInstructionPacketV1.js +1 -0
- package/dist/src/evaluation/upstreamArtifacts/readJsonArtifact.js +53 -0
- package/dist/src/evaluation/upstreamArtifacts/readMyDevKitContextCapsuleV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readMyDevKitRetrievalAuditRecordV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readOrchestratorWorkflowInstructionPacketV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/runtimeValidation.js +131 -0
- package/dist/src/evaluation/upstreamArtifacts/schemaVersion.js +32 -0
- package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +1208 -0
- package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +105 -0
- package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorWorkflowInstructionPacketV1.js +235 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/executeV043StageContextStrategy.js +46 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/index.js +9 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/loadV043StrategyArtifacts.js +286 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/plugin.js +39 -1
- package/dist/src/experiments/plugins/contextStrategyComparison/readV043FullWorkflowLibraryFixture.js +162 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/resolveV043StrategyInputs.js +43 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/resultMapping.js +3 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/runV043StageContextStrategyWithAssurance.js +190 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/v043FullWorkflowLibraryFixture.js +1 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/v043RunAssuranceTypes.js +1 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyExecutionTypes.js +1 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyIds.js +13 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/v043StrategyInputContracts.js +1 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/validateV043RunAssuranceConfig.js +59 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/validateV043StrategyInput.js +252 -0
- package/dist/src/report/experiments/buildContextStrategyComparisonV043Report.js +398 -0
- package/dist/src/report/experiments/buildPluginExperimentReport.js +21 -6
- package/dist/src/report/experiments/contextStrategyComparisonV043ReportModel.js +1 -0
- package/dist/src/report/experiments/index.js +4 -0
- package/dist/src/report/experiments/renderContextStrategyComparisonV043Html.js +234 -0
- package/dist/src/report/experiments/renderPluginExperimentReportHtml.js +3 -0
- package/dist/src/report/experiments/renderPluginExperimentReportText.js +225 -0
- package/dist/src/report/experiments/writePluginExperimentReports.js +3 -0
- package/dist/src/securityValidation/attackScenarios/scenarios/secretLeakageScenario.js +215 -9
- package/docs/METRICS.md +56 -10
- package/package.json +1 -1
- package/tests/fixtures/full-workflow-library/complete-v1.0.0.json +24 -0
- package/tests/fixtures/full-workflow-library/future-minor-v1.1.0-additive.json +25 -0
- package/tests/fixtures/stage-context-expectations/complete-v1.0.0.json +230 -0
- package/tests/fixtures/stage-context-expectations/future-minor-v1.1.0-additive.json +232 -0
- package/tests/fixtures/stage-context-expectations/invalid/malformed-json.txt +1 -0
- package/tests/fixtures/stage-context-expectations/invalid/non-object-root.json +1 -0
- package/tests/fixtures/stage-context-expectations/minimal-v1.0.0.json +18 -0
- package/tests/fixtures/upstream-artifacts/invalid/malformed-json.txt +1 -0
- package/tests/fixtures/upstream-artifacts/invalid/non-object-root.json +1 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/complete-v1.0.0.json +504 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/future-minor-v1.1.0-additive.json +955 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/complete-v1.0.0.json +190 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/future-minor-v1.1.0-additive.json +327 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/complete-v1.0.0.json +160 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/future-minor-v1.1.0-additive.json +186 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { V043_REPORT_DETAIL_LIMIT, } from "./contextStrategyComparisonV043ReportModel.js";
|
|
2
|
+
const INTERPRETATION_SUMMARY = "Stage-context strategies are reported independently using direct evidence, explicit availability states, target-immutability evidence, and repeated-run determinism. No composite ranking or winning strategy is calculated.";
|
|
3
|
+
const INTERPRETATION_LIMITATIONS = [
|
|
4
|
+
"The published upstream artifacts do not expose considered-but-unselected reads.",
|
|
5
|
+
"The published upstream artifacts do not expose unnecessary-read evidence.",
|
|
6
|
+
"Estimated token counts use ceil(characterCount / 4) per source and are not provider telemetry.",
|
|
7
|
+
"Unavailable and not-applicable values are distinct from zero.",
|
|
8
|
+
];
|
|
9
|
+
function boundItems(source) {
|
|
10
|
+
const items = source.slice(0, V043_REPORT_DETAIL_LIMIT);
|
|
11
|
+
return {
|
|
12
|
+
totalCount: source.length,
|
|
13
|
+
displayedCount: items.length,
|
|
14
|
+
omittedCount: source.length - items.length,
|
|
15
|
+
items,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function buildContextStrategyComparisonV043Report(run) {
|
|
19
|
+
if (run.pluginId !== "context-strategy-comparison")
|
|
20
|
+
return null;
|
|
21
|
+
const candidate = run;
|
|
22
|
+
const executions = candidate.v043StageContextExecutions;
|
|
23
|
+
const evaluations = candidate.v043StageContextEvaluations;
|
|
24
|
+
const assurances = candidate.v043StageContextRunAssurance;
|
|
25
|
+
if (executions === undefined && evaluations === undefined && assurances === undefined) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
if (!Array.isArray(executions) || !Array.isArray(evaluations) || !Array.isArray(assurances)) {
|
|
29
|
+
throw new Error("Invalid v0.4.3 report source: execution, evaluation, and assurance arrays are inconsistent.");
|
|
30
|
+
}
|
|
31
|
+
if (executions.length !== evaluations.length || executions.length !== assurances.length) {
|
|
32
|
+
throw new Error("Invalid v0.4.3 report source: execution, evaluation, and assurance arrays are inconsistent.");
|
|
33
|
+
}
|
|
34
|
+
for (let index = 0; index < executions.length; index += 1) {
|
|
35
|
+
const ids = [
|
|
36
|
+
executions[index].strategyId,
|
|
37
|
+
evaluations[index].strategyId,
|
|
38
|
+
assurances[index].strategyId,
|
|
39
|
+
].filter((id) => id !== null && id !== undefined);
|
|
40
|
+
const distinct = new Set(ids);
|
|
41
|
+
if (distinct.size > 1) {
|
|
42
|
+
throw new Error("Invalid v0.4.3 report source: execution, evaluation, and assurance arrays are inconsistent.");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const strategies = executions.map((execution, index) => buildStrategyReport(execution, evaluations[index], assurances[index]));
|
|
46
|
+
return {
|
|
47
|
+
schemaVersion: "1.0.0",
|
|
48
|
+
detailLimit: V043_REPORT_DETAIL_LIMIT,
|
|
49
|
+
summary: buildSummary(executions, evaluations, assurances),
|
|
50
|
+
strategies,
|
|
51
|
+
interpretation: {
|
|
52
|
+
summary: INTERPRETATION_SUMMARY,
|
|
53
|
+
limitations: [...INTERPRETATION_LIMITATIONS],
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function buildSummary(executions, evaluations, assurances) {
|
|
58
|
+
return {
|
|
59
|
+
strategyCount: executions.length,
|
|
60
|
+
completedExecutionCount: executions.filter((e) => e.status === "completed").length,
|
|
61
|
+
invalidInputExecutionCount: executions.filter((e) => e.status === "invalid-input").length,
|
|
62
|
+
failedExecutionCount: executions.filter((e) => e.status === "failed").length,
|
|
63
|
+
completedEvaluationCount: evaluations.filter((e) => e.status === "completed").length,
|
|
64
|
+
notApplicableEvaluationCount: evaluations.filter((e) => e.status === "not-applicable").length,
|
|
65
|
+
failedEvaluationCount: evaluations.filter((e) => e.status === "failed").length,
|
|
66
|
+
passedAssuranceCount: assurances.filter((a) => a.status === "passed").length,
|
|
67
|
+
failedAssuranceCount: assurances.filter((a) => a.status === "failed").length,
|
|
68
|
+
notApplicableAssuranceCount: assurances.filter((a) => a.status === "not-applicable").length,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function buildStrategyReport(execution, evaluation, assurance) {
|
|
72
|
+
return {
|
|
73
|
+
strategyId: assurance.strategyId,
|
|
74
|
+
artifacts: buildArtifactMetadata(execution),
|
|
75
|
+
execution: buildExecutionSummary(execution),
|
|
76
|
+
evaluation: buildEvaluationSummary(evaluation),
|
|
77
|
+
assurance: buildAssuranceSummary(assurance),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function buildExecutionSummary(execution) {
|
|
81
|
+
if (execution.status === "completed") {
|
|
82
|
+
return { status: "completed", issues: boundItems([]) };
|
|
83
|
+
}
|
|
84
|
+
const issues = execution.issues.map(buildIssueFromExecutionIssue);
|
|
85
|
+
return { status: execution.status, issues: boundItems(issues) };
|
|
86
|
+
}
|
|
87
|
+
function buildIssueFromExecutionIssue(issue) {
|
|
88
|
+
return {
|
|
89
|
+
code: issue.code,
|
|
90
|
+
fieldPath: issue.fieldPath ?? null,
|
|
91
|
+
message: issue.message,
|
|
92
|
+
runNumber: null,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function buildArtifactMetadata(execution) {
|
|
96
|
+
if (execution.status !== "completed") {
|
|
97
|
+
return boundItems([]);
|
|
98
|
+
}
|
|
99
|
+
const entries = [];
|
|
100
|
+
entries.push({
|
|
101
|
+
sourceInstance: "expectations",
|
|
102
|
+
artifactKind: "expectation-fixture",
|
|
103
|
+
sourcePath: execution.expectationsSourcePath,
|
|
104
|
+
schemaVersion: execution.expectations.schemaVersion,
|
|
105
|
+
generatedAt: null,
|
|
106
|
+
producerName: null,
|
|
107
|
+
producerVersion: null,
|
|
108
|
+
role: null,
|
|
109
|
+
workflowId: null,
|
|
110
|
+
stageId: null,
|
|
111
|
+
catalogSchemaVersion: null,
|
|
112
|
+
catalogVersion: null,
|
|
113
|
+
fixtureId: null,
|
|
114
|
+
caseId: execution.expectations.caseId,
|
|
115
|
+
title: execution.expectations.title,
|
|
116
|
+
});
|
|
117
|
+
const payload = execution.payload;
|
|
118
|
+
if ("contextArtifacts" in payload) {
|
|
119
|
+
const contextArtifacts = payload.contextArtifacts;
|
|
120
|
+
contextArtifacts.forEach((pair, index) => {
|
|
121
|
+
entries.push(...buildContextArtifactPairMetadata(pair, `contextArtifacts[${index}]`));
|
|
122
|
+
});
|
|
123
|
+
entries.push(buildWorkflowInstructionPacketMetadata(payload.workflowInstructionPacketSourcePath, payload.workflowInstructionPacket));
|
|
124
|
+
}
|
|
125
|
+
else if ("fullWorkflowLibrary" in payload) {
|
|
126
|
+
entries.push(buildFullWorkflowLibraryMetadata(payload.fullWorkflowLibrarySourcePath, payload.fullWorkflowLibrary));
|
|
127
|
+
}
|
|
128
|
+
else if ("workflowInstructionPacket" in payload) {
|
|
129
|
+
entries.push(buildWorkflowInstructionPacketMetadata(payload.workflowInstructionPacketSourcePath, payload.workflowInstructionPacket));
|
|
130
|
+
}
|
|
131
|
+
else if ("testImplementation" in payload) {
|
|
132
|
+
entries.push(...buildContextArtifactPairMetadata(payload.architecture, "architecture"));
|
|
133
|
+
entries.push(...buildContextArtifactPairMetadata(payload.implementation, "implementation"));
|
|
134
|
+
entries.push(...buildContextArtifactPairMetadata(payload.testImplementation, "testImplementation"));
|
|
135
|
+
}
|
|
136
|
+
else if ("implementation" in payload) {
|
|
137
|
+
entries.push(...buildContextArtifactPairMetadata(payload.architecture, "architecture"));
|
|
138
|
+
entries.push(...buildContextArtifactPairMetadata(payload.implementation, "implementation"));
|
|
139
|
+
}
|
|
140
|
+
else if ("architecture" in payload) {
|
|
141
|
+
entries.push(...buildContextArtifactPairMetadata(payload.architecture, "architecture"));
|
|
142
|
+
}
|
|
143
|
+
return boundItems(entries);
|
|
144
|
+
}
|
|
145
|
+
function buildContextArtifactPairMetadata(pair, sourceInstancePrefix) {
|
|
146
|
+
const entries = [
|
|
147
|
+
{
|
|
148
|
+
sourceInstance: `${sourceInstancePrefix}.contextCapsule`,
|
|
149
|
+
artifactKind: "context-capsule",
|
|
150
|
+
sourcePath: pair.contextCapsuleSourcePath,
|
|
151
|
+
schemaVersion: pair.contextCapsule.schemaVersion,
|
|
152
|
+
generatedAt: pair.contextCapsule.generatedAt,
|
|
153
|
+
producerName: pair.contextCapsule.tool.name,
|
|
154
|
+
producerVersion: pair.contextCapsule.tool.version,
|
|
155
|
+
role: pair.contextCapsule.request.role,
|
|
156
|
+
workflowId: null,
|
|
157
|
+
stageId: null,
|
|
158
|
+
catalogSchemaVersion: null,
|
|
159
|
+
catalogVersion: null,
|
|
160
|
+
fixtureId: null,
|
|
161
|
+
caseId: null,
|
|
162
|
+
title: null,
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
if (pair.retrievalAuditRecord) {
|
|
166
|
+
entries.push({
|
|
167
|
+
sourceInstance: `${sourceInstancePrefix}.retrievalAuditRecord`,
|
|
168
|
+
artifactKind: "retrieval-audit-record",
|
|
169
|
+
sourcePath: pair.retrievalAuditRecordSourcePath ?? "",
|
|
170
|
+
schemaVersion: pair.retrievalAuditRecord.schemaVersion,
|
|
171
|
+
generatedAt: pair.retrievalAuditRecord.generatedAt,
|
|
172
|
+
producerName: pair.retrievalAuditRecord.tool.name,
|
|
173
|
+
producerVersion: pair.retrievalAuditRecord.tool.version,
|
|
174
|
+
role: pair.retrievalAuditRecord.request.role,
|
|
175
|
+
workflowId: null,
|
|
176
|
+
stageId: null,
|
|
177
|
+
catalogSchemaVersion: null,
|
|
178
|
+
catalogVersion: null,
|
|
179
|
+
fixtureId: null,
|
|
180
|
+
caseId: null,
|
|
181
|
+
title: null,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return entries;
|
|
185
|
+
}
|
|
186
|
+
function buildWorkflowInstructionPacketMetadata(sourcePath, packet) {
|
|
187
|
+
return {
|
|
188
|
+
sourceInstance: "workflowInstructionPacket",
|
|
189
|
+
artifactKind: "workflow-instruction-packet",
|
|
190
|
+
sourcePath,
|
|
191
|
+
schemaVersion: packet.schemaVersion,
|
|
192
|
+
generatedAt: null,
|
|
193
|
+
producerName: null,
|
|
194
|
+
producerVersion: null,
|
|
195
|
+
role: null,
|
|
196
|
+
workflowId: packet.workflowId,
|
|
197
|
+
stageId: packet.stageId,
|
|
198
|
+
catalogSchemaVersion: packet.catalogSchemaVersion,
|
|
199
|
+
catalogVersion: packet.catalogVersion,
|
|
200
|
+
fixtureId: null,
|
|
201
|
+
caseId: null,
|
|
202
|
+
title: null,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function buildFullWorkflowLibraryMetadata(sourcePath, library) {
|
|
206
|
+
return {
|
|
207
|
+
sourceInstance: "fullWorkflowLibrary",
|
|
208
|
+
artifactKind: "full-workflow-library",
|
|
209
|
+
sourcePath,
|
|
210
|
+
schemaVersion: library.schemaVersion,
|
|
211
|
+
generatedAt: null,
|
|
212
|
+
producerName: null,
|
|
213
|
+
producerVersion: null,
|
|
214
|
+
role: null,
|
|
215
|
+
workflowId: null,
|
|
216
|
+
stageId: null,
|
|
217
|
+
catalogSchemaVersion: null,
|
|
218
|
+
catalogVersion: null,
|
|
219
|
+
fixtureId: library.fixtureId,
|
|
220
|
+
caseId: null,
|
|
221
|
+
title: library.title,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function buildEvaluationSummary(evaluation) {
|
|
225
|
+
if (evaluation.status !== "completed") {
|
|
226
|
+
return {
|
|
227
|
+
status: evaluation.status,
|
|
228
|
+
reason: evaluation.reason,
|
|
229
|
+
warnings: boundItems([]),
|
|
230
|
+
expectationMatches: boundItems([]),
|
|
231
|
+
observedEvidence: boundItems([]),
|
|
232
|
+
metrics: null,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
status: "completed",
|
|
237
|
+
reason: null,
|
|
238
|
+
warnings: boundItems(evaluation.warnings),
|
|
239
|
+
expectationMatches: boundItems(evaluation.expectationMatches.map(buildExpectationMatch)),
|
|
240
|
+
observedEvidence: boundItems(evaluation.observedEvidence.map(buildObservedEvidence)),
|
|
241
|
+
metrics: buildMetrics(evaluation.metrics),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function buildExpectationMatch(match) {
|
|
245
|
+
return {
|
|
246
|
+
expectationId: match.expectationId,
|
|
247
|
+
inclusion: match.inclusion,
|
|
248
|
+
sourceArtifact: match.sourceArtifact,
|
|
249
|
+
category: match.category,
|
|
250
|
+
targetKey: match.targetKey,
|
|
251
|
+
outcome: match.outcome,
|
|
252
|
+
matchedSourceInstances: match.matchedSourceInstances,
|
|
253
|
+
matchedSourceFieldPaths: match.matchedSourceFieldPaths,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function buildObservedEvidence(evidence) {
|
|
257
|
+
return {
|
|
258
|
+
sourceArtifact: evidence.sourceArtifact,
|
|
259
|
+
sourceInstance: evidence.sourceInstance,
|
|
260
|
+
category: evidence.category,
|
|
261
|
+
targetKey: evidence.targetKey,
|
|
262
|
+
sourceFieldPath: evidence.sourceFieldPath,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function buildMetrics(metrics) {
|
|
266
|
+
return {
|
|
267
|
+
requiredEvidenceRecall: buildRatioMetric(metrics.requiredEvidenceRecall),
|
|
268
|
+
allowedEvidenceCoverage: buildRatioMetric(metrics.allowedEvidenceCoverage),
|
|
269
|
+
forbiddenEvidenceInclusion: buildRatioMetric(metrics.forbiddenEvidenceInclusion),
|
|
270
|
+
irrelevantFileInclusion: buildCountMetric(metrics.irrelevantFileInclusion),
|
|
271
|
+
irrelevantInstructionInclusion: buildCountMetric(metrics.irrelevantInstructionInclusion),
|
|
272
|
+
requiredProvenanceRecall: buildRatioMetric(metrics.requiredProvenanceRecall),
|
|
273
|
+
responsibilityMappingCompleteness: boundItems(metrics.responsibilityMappingCompleteness.map(buildResponsibilityMapping)),
|
|
274
|
+
stateComparisons: boundItems(metrics.stateComparisons.map(buildStateComparison)),
|
|
275
|
+
contextSize: buildContextSize(metrics.contextSize),
|
|
276
|
+
consideredButUnselectedReads: buildCountMetric(metrics.consideredButUnselectedReads),
|
|
277
|
+
unnecessaryReads: buildCountMetric(metrics.unnecessaryReads),
|
|
278
|
+
targetImmutability: buildCountMetric(metrics.targetImmutability),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function buildRatioMetric(metric) {
|
|
282
|
+
return {
|
|
283
|
+
availability: metric.availability,
|
|
284
|
+
numerator: metric.numerator,
|
|
285
|
+
denominator: metric.denominator,
|
|
286
|
+
rate: metric.rate,
|
|
287
|
+
matchedExpectationIds: boundItems(metric.matchedExpectationIds),
|
|
288
|
+
missingExpectationIds: boundItems(metric.missingExpectationIds),
|
|
289
|
+
reason: metric.reason,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function buildCountMetric(metric) {
|
|
293
|
+
return {
|
|
294
|
+
availability: metric.availability,
|
|
295
|
+
count: metric.count,
|
|
296
|
+
evidenceKeys: boundItems(metric.evidenceKeys),
|
|
297
|
+
reason: metric.reason,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function buildResponsibilityMapping(mapping) {
|
|
301
|
+
return {
|
|
302
|
+
sourceArtifact: mapping.sourceArtifact,
|
|
303
|
+
sourceInstance: mapping.sourceInstance,
|
|
304
|
+
requested: mapping.requested,
|
|
305
|
+
operational: mapping.operational,
|
|
306
|
+
mappedCount: mapping.mappedCount,
|
|
307
|
+
partiallyMappedCount: mapping.partiallyMappedCount,
|
|
308
|
+
unmappedCount: mapping.unmappedCount,
|
|
309
|
+
notApplicableCount: mapping.notApplicableCount,
|
|
310
|
+
denominator: mapping.denominator,
|
|
311
|
+
mappedRate: mapping.mappedRate,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function buildStateComparison(comparison) {
|
|
315
|
+
return {
|
|
316
|
+
sourceArtifact: comparison.sourceArtifact,
|
|
317
|
+
sourceInstance: comparison.sourceInstance,
|
|
318
|
+
expectationFieldPath: comparison.expectationFieldPath,
|
|
319
|
+
artifactFieldPath: comparison.artifactFieldPath,
|
|
320
|
+
availability: comparison.availability,
|
|
321
|
+
expected: comparison.expected,
|
|
322
|
+
actual: comparison.actual,
|
|
323
|
+
matched: comparison.matched,
|
|
324
|
+
reason: comparison.reason,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function buildContextSize(size) {
|
|
328
|
+
return {
|
|
329
|
+
sources: boundItems(size.sources.map((source) => ({
|
|
330
|
+
sourceInstance: source.sourceInstance,
|
|
331
|
+
sourceKind: source.sourceKind,
|
|
332
|
+
characterCount: source.characterCount,
|
|
333
|
+
estimatedTokenCount: source.estimatedTokenCount,
|
|
334
|
+
}))),
|
|
335
|
+
totalCharacterCount: size.totalCharacterCount,
|
|
336
|
+
totalEstimatedTokenCount: size.totalEstimatedTokenCount,
|
|
337
|
+
tokenEstimateFormula: "ceil(characterCount / 4) per source",
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function buildAssuranceSummary(assurance) {
|
|
341
|
+
return {
|
|
342
|
+
status: assurance.status,
|
|
343
|
+
repeatCount: assurance.repeatCount,
|
|
344
|
+
runRecords: boundItems(assurance.runRecords.map(buildRunRecord)),
|
|
345
|
+
determinism: buildDeterminism(assurance.determinism),
|
|
346
|
+
issues: boundItems(assurance.issues.map((issue) => ({
|
|
347
|
+
code: issue.code,
|
|
348
|
+
fieldPath: issue.fieldPath,
|
|
349
|
+
message: issue.message,
|
|
350
|
+
runNumber: issue.runNumber,
|
|
351
|
+
}))),
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function buildRunRecord(record) {
|
|
355
|
+
const targetImmutability = record.targetImmutability;
|
|
356
|
+
if (targetImmutability.availability === "available") {
|
|
357
|
+
return {
|
|
358
|
+
runNumber: record.runNumber,
|
|
359
|
+
executionStatus: record.executionStatus,
|
|
360
|
+
evaluationStatus: record.evaluationStatus,
|
|
361
|
+
targetImmutabilityAvailability: "available",
|
|
362
|
+
targetImmutabilityStatus: targetImmutability.comparison.status,
|
|
363
|
+
newMutationCount: targetImmutability.comparison.newMutationCount,
|
|
364
|
+
targetImmutabilityReason: null,
|
|
365
|
+
mutations: boundItems(targetImmutability.comparison.mutations.map(buildTargetMutation)),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
runNumber: record.runNumber,
|
|
370
|
+
executionStatus: record.executionStatus,
|
|
371
|
+
evaluationStatus: record.evaluationStatus,
|
|
372
|
+
targetImmutabilityAvailability: "unavailable",
|
|
373
|
+
targetImmutabilityStatus: null,
|
|
374
|
+
newMutationCount: null,
|
|
375
|
+
targetImmutabilityReason: targetImmutability.reason,
|
|
376
|
+
mutations: boundItems([]),
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
function buildTargetMutation(mutation) {
|
|
380
|
+
return {
|
|
381
|
+
id: mutation.id,
|
|
382
|
+
kind: mutation.kind,
|
|
383
|
+
fieldPath: mutation.fieldPath,
|
|
384
|
+
before: mutation.before,
|
|
385
|
+
after: mutation.after,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function buildDeterminism(determinism) {
|
|
389
|
+
return {
|
|
390
|
+
availability: determinism.availability,
|
|
391
|
+
repeatCount: determinism.repeatCount,
|
|
392
|
+
deterministic: determinism.deterministic,
|
|
393
|
+
baselineSha256: determinism.baselineSha256,
|
|
394
|
+
runDigests: boundItems(determinism.runDigests.map((digest) => ({ runNumber: digest.runNumber, sha256: digest.sha256 }))),
|
|
395
|
+
mismatchRunNumbers: [...determinism.mismatchRunNumbers],
|
|
396
|
+
reason: determinism.reason,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { buildContextStrategyComparisonV043Report } from "./buildContextStrategyComparisonV043Report.js";
|
|
3
|
+
const V043_BULK_ARRAY_KEYS = [
|
|
4
|
+
"v043StageContextExecutions",
|
|
5
|
+
"v043StageContextEvaluations",
|
|
6
|
+
"v043StageContextRunAssurance",
|
|
7
|
+
];
|
|
2
8
|
export function buildPluginExperimentReport(args) {
|
|
3
9
|
const outputRoot = args.outputRoot ?? readString(args.run.metadata?.outputRoot) ?? null;
|
|
4
10
|
const allOutcomes = args.run.cases.flatMap((experimentCase) => experimentCase.outcomes);
|
|
11
|
+
const contextStrategyComparisonV043 = buildContextStrategyComparisonV043Report(args.run);
|
|
12
|
+
const rawRun = { ...args.run, artifacts: relativizeArtifacts(args.run.artifacts, outputRoot) };
|
|
13
|
+
for (const key of V043_BULK_ARRAY_KEYS) {
|
|
14
|
+
delete rawRun[key];
|
|
15
|
+
}
|
|
5
16
|
return {
|
|
6
17
|
metadata: {
|
|
7
18
|
generatedAt: args.generatedAt ?? new Date().toISOString(),
|
|
@@ -25,11 +36,9 @@ export function buildPluginExperimentReport(args) {
|
|
|
25
36
|
failures: args.run.failures,
|
|
26
37
|
skippedOutcomes: allOutcomes.filter((outcome) => outcome.status === "skipped"),
|
|
27
38
|
findings: buildFindings(args.run),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
artifacts: relativizeArtifacts(args.run.artifacts, outputRoot),
|
|
32
|
-
},
|
|
39
|
+
contextStrategyComparisonV043,
|
|
40
|
+
interpretation: buildInterpretation(args.run, contextStrategyComparisonV043),
|
|
41
|
+
rawRun,
|
|
33
42
|
};
|
|
34
43
|
}
|
|
35
44
|
function buildVariantSummary(variant, outcomes) {
|
|
@@ -85,7 +94,13 @@ function buildFindings(run) {
|
|
|
85
94
|
...skipped,
|
|
86
95
|
];
|
|
87
96
|
}
|
|
88
|
-
function buildInterpretation(run) {
|
|
97
|
+
function buildInterpretation(run, contextStrategyComparisonV043) {
|
|
98
|
+
if (run.pluginId === "context-strategy-comparison" && (contextStrategyComparisonV043?.summary.strategyCount ?? 0) > 0) {
|
|
99
|
+
return {
|
|
100
|
+
summary: `Stage-context evidence was recorded for ${contextStrategyComparisonV043.summary.strategyCount} strategy executions. Review each strategy independently; this report does not calculate a composite ranking or winning strategy.`,
|
|
101
|
+
recommendedNextStep: "Review required evidence, irrelevant inclusion, state comparisons, target immutability, determinism, and explicit unavailable or not-applicable metrics for each strategy.",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
89
104
|
if (run.pluginId === "context-strategy-comparison") {
|
|
90
105
|
const tokenSavings = metricNumber(run.metrics, "average-token-savings-percent");
|
|
91
106
|
const correctnessDelta = metricNumber(run.metrics, "average-correctness-delta");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const V043_REPORT_DETAIL_LIMIT = 100;
|
|
@@ -2,3 +2,7 @@ export * from "./buildPluginExperimentReport.js";
|
|
|
2
2
|
export * from "./experimentReportModel.js";
|
|
3
3
|
export * from "./renderPluginExperimentReportHtml.js";
|
|
4
4
|
export * from "./writePluginExperimentReports.js";
|
|
5
|
+
export * from "./contextStrategyComparisonV043ReportModel.js";
|
|
6
|
+
export { buildContextStrategyComparisonV043Report } from "./buildContextStrategyComparisonV043Report.js";
|
|
7
|
+
export { renderContextStrategyComparisonV043Html } from "./renderContextStrategyComparisonV043Html.js";
|
|
8
|
+
export { renderPluginExperimentReportText } from "./renderPluginExperimentReportText.js";
|