@dailephd/my-dev-kit-lab 0.4.3 → 0.4.5
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 +468 -0
- package/README.md +8 -1
- package/dist/scripts/report-context-integrity-smoke.js +70 -0
- package/dist/src/evaluation/ecosystemFixtures/index.js +3 -0
- package/dist/src/evaluation/ecosystemFixtures/loadContextIntegrityFixture.js +102 -0
- package/dist/src/evaluation/ecosystemFixtures/manifestTypes.js +1 -0
- package/dist/src/evaluation/ecosystemFixtures/validateManifest.js +82 -0
- package/dist/src/evaluation/ecosystemFixtures/verifyFixtureHashes.js +45 -0
- package/dist/src/evaluation/stageContextExpectations/producerReadinessExpectationTypes.js +8 -0
- package/dist/src/evaluation/stageContextExpectations/validation.js +200 -0
- package/dist/src/evaluation/stageContextMetrics/calculateAllocationMetrics.js +265 -0
- package/dist/src/evaluation/stageContextMetrics/calculateConditionCoverageMetrics.js +74 -0
- package/dist/src/evaluation/stageContextMetrics/calculateCriticalityMetrics.js +112 -0
- package/dist/src/evaluation/stageContextMetrics/calculateOwnerMetrics.js +84 -0
- package/dist/src/evaluation/stageContextMetrics/calculateProducerConditionAgreement.js +113 -0
- package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +212 -0
- package/dist/src/evaluation/stageContextMetrics/calculateRunIntegrityAgreement.js +309 -0
- package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +60 -0
- package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +144 -0
- package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +198 -0
- package/dist/src/evaluation/stageContextMetrics/index.js +11 -0
- package/dist/src/evaluation/stageContextMetrics/producerReadinessMetricTypes.js +1 -0
- package/dist/src/evaluation/stageContextMetrics/runIntegrityAgreementTypes.js +1 -0
- package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +17 -0
- package/dist/src/evaluation/stageContextSelectors/index.js +1 -0
- package/dist/src/evaluation/stageContextSelectors/orchestratorRunIntegritySelectors.js +64 -0
- package/dist/src/evaluation/upstreamArtifacts/index.js +8 -0
- package/dist/src/evaluation/upstreamArtifacts/orchestratorContextReadinessResultV1.js +247 -0
- package/dist/src/evaluation/upstreamArtifacts/orchestratorRunIntegrityV1.js +33 -0
- package/dist/src/evaluation/upstreamArtifacts/readImplementationContextPacketV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readImplementationContextRetrievalReportV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readOrchestratorRunIntegrityV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readSupplementalContextTextFile.js +29 -0
- package/dist/src/evaluation/upstreamArtifacts/readTestContextPacketV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/readTestContextRetrievalReportV1.js +9 -0
- package/dist/src/evaluation/upstreamArtifacts/supplementalContextTextParser.js +75 -0
- package/dist/src/evaluation/upstreamArtifacts/supplementalContextTypes.js +152 -0
- package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +59 -2
- package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +15 -3
- package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorRunIntegrityV1.js +177 -0
- package/dist/src/evaluation/upstreamArtifacts/validateSupplementalContextDocumentV1.js +148 -0
- package/dist/src/experiments/plugins/contextStrategyComparison/loadV043StrategyArtifacts.js +117 -6
- package/dist/src/experiments/plugins/contextStrategyComparison/runV043StageContextStrategyWithAssurance.js +18 -3
- package/dist/src/experiments/plugins/contextStrategyComparison/validateV043StrategyInput.js +17 -3
- package/dist/src/report/experiments/buildContextIntegrityReport.js +204 -0
- package/dist/src/report/experiments/buildContextStrategyComparisonV043Report.js +122 -0
- package/dist/src/report/experiments/contextIntegrityReportModel.js +1 -0
- package/dist/src/report/experiments/index.js +5 -0
- package/dist/src/report/experiments/renderContextIntegrityHtml.js +98 -0
- package/dist/src/report/experiments/renderContextIntegrityJsonReport.js +3 -0
- package/dist/src/report/experiments/renderContextIntegrityText.js +111 -0
- package/dist/src/report/experiments/renderContextStrategyComparisonV043Html.js +62 -0
- package/dist/src/report/experiments/renderPluginExperimentReportText.js +67 -0
- package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +33 -0
- package/dist/src/securityValidation/packageChecks/runPackageChecks.js +11 -5
- package/docs/METRICS.md +111 -0
- package/package.json +5 -3
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/derived/run-integrity-evidence.json +99 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-audit.json +1585 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-capsule.json +11455 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/00-request.txt +1 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/architecture-context-packet.txt +82 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/behavior-model.txt +104 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/final-report.txt +41 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-context-packet.txt +114 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-report.txt +92 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/judge-report.txt +34 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/pseudocode-packet.txt +244 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/request-brief.txt +40 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-context-packet.txt +93 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-implementation-report.txt +69 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-strategy-packet.txt +354 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/verification-report.txt +85 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/derived/run-integrity-evidence.json +98 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-audit.json +1169 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-request.json +29 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-audit.json +1494 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-capsule.json +11364 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-request.json +33 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/test-request.json +74 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/architecture-context-retrieval-report.txt +58 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/implementation-context-retrieval-report.txt +75 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/test-context-retrieval-report.txt +84 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/run.json +62 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/my-dev-kit-version.txt +1 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/orchestrator-version.txt +1 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/corrected-replay-manifest.json +19 -0
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/failed-run-manifest.json +56 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/PROVENANCE.txt +18 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/context-capsule/complete-v1.0.0.json +556 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/retrieval-audit-record/complete-v1.0.0.json +238 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +13 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +7874 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +1076 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/PROVENANCE.txt +31 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/ready-pass-final-pass.json +132 -0
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/refresh-required-need-context.json +146 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { captureTargetSnapshot, compareTargetSnapshots } from "../../../evaluation/targetImmutability/index.js";
|
|
2
2
|
import { calculateStageContextDeterminism } from "../../../evaluation/stageContextDeterminism/index.js";
|
|
3
|
-
import { evaluateV043StageContextExecution } from "../../../evaluation/stageContextMetrics/index.js";
|
|
3
|
+
import { buildProducerReadinessBridgeInputFromCombinedPayload, evaluateProducerReadinessBridge, evaluateV043StageContextExecution } from "../../../evaluation/stageContextMetrics/index.js";
|
|
4
4
|
import { executeV043StageContextStrategy } from "./executeV043StageContextStrategy.js";
|
|
5
5
|
async function buildRunWithTargetImmutability(targetConfig, input) {
|
|
6
6
|
if (targetConfig === undefined) {
|
|
@@ -57,6 +57,15 @@ async function buildRunWithTargetImmutability(targetConfig, input) {
|
|
|
57
57
|
targetImmutability: { availability: "available", comparison, reason: null }
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
+
// v0.4.4 Batch 3: computed exactly once per run, immediately after execution, from the
|
|
61
|
+
// already-loaded execution payload -- never rereads artifacts, never reruns the strategy.
|
|
62
|
+
function buildProducerReadinessBridgeResult(execution) {
|
|
63
|
+
if (execution.status !== "completed" || execution.strategyId !== "combined-bounded-stage-context")
|
|
64
|
+
return null;
|
|
65
|
+
const payload = execution.payload;
|
|
66
|
+
const bridgeInput = buildProducerReadinessBridgeInputFromCombinedPayload(payload, execution.expectations);
|
|
67
|
+
return evaluateProducerReadinessBridge(bridgeInput);
|
|
68
|
+
}
|
|
60
69
|
function computeStatus(issues, config) {
|
|
61
70
|
if (issues.length > 0)
|
|
62
71
|
return "failed";
|
|
@@ -69,23 +78,27 @@ export async function runV043StageContextStrategyWithAssurance(input, config) {
|
|
|
69
78
|
const issues = [];
|
|
70
79
|
let primaryExecution;
|
|
71
80
|
let primaryEvaluation;
|
|
81
|
+
let primaryProducerReadinessBridge = null;
|
|
72
82
|
try {
|
|
73
83
|
for (let runNumber = 1; runNumber <= config.repeatCount; runNumber += 1) {
|
|
74
84
|
const { execution, targetImmutability } = await buildRunWithTargetImmutability(config.targetImmutability, input);
|
|
75
85
|
const evaluation = evaluateV043StageContextExecution(execution, { targetImmutability });
|
|
86
|
+
const producerReadinessBridge = buildProducerReadinessBridgeResult(execution);
|
|
76
87
|
if (runNumber === 1) {
|
|
77
88
|
primaryExecution = execution;
|
|
78
89
|
primaryEvaluation = evaluation;
|
|
90
|
+
primaryProducerReadinessBridge = producerReadinessBridge;
|
|
79
91
|
}
|
|
80
92
|
runRecords.push({
|
|
81
93
|
runNumber,
|
|
82
94
|
executionStatus: execution.status,
|
|
83
95
|
evaluationStatus: evaluation.status,
|
|
84
|
-
targetImmutability
|
|
96
|
+
targetImmutability,
|
|
97
|
+
producerReadinessBridge
|
|
85
98
|
});
|
|
86
99
|
determinismCandidates.push({
|
|
87
100
|
runNumber,
|
|
88
|
-
value: { execution, evaluation, targetImmutability }
|
|
101
|
+
value: { execution, evaluation, targetImmutability, producerReadinessBridge }
|
|
89
102
|
});
|
|
90
103
|
if (execution.status !== "completed") {
|
|
91
104
|
issues.push({
|
|
@@ -147,6 +160,7 @@ export async function runV043StageContextStrategyWithAssurance(input, config) {
|
|
|
147
160
|
repeatCount: config.repeatCount,
|
|
148
161
|
primaryExecution: primaryExecution,
|
|
149
162
|
primaryEvaluation: primaryEvaluation,
|
|
163
|
+
primaryProducerReadinessBridge,
|
|
150
164
|
runRecords,
|
|
151
165
|
determinism,
|
|
152
166
|
issues
|
|
@@ -175,6 +189,7 @@ export async function runV043StageContextStrategyWithAssurance(input, config) {
|
|
|
175
189
|
repeatCount: config.repeatCount,
|
|
176
190
|
primaryExecution: fallbackExecution,
|
|
177
191
|
primaryEvaluation: fallbackEvaluation,
|
|
192
|
+
primaryProducerReadinessBridge,
|
|
178
193
|
runRecords,
|
|
179
194
|
determinism: fallbackDeterminism,
|
|
180
195
|
issues: [
|
|
@@ -45,7 +45,12 @@ const STRATEGY_CONTRACTS = {
|
|
|
45
45
|
fields: [
|
|
46
46
|
{ name: "expectationsPath", kind: "required-path" },
|
|
47
47
|
{ name: "contextArtifacts", kind: "required-array" },
|
|
48
|
-
{ name: "workflowInstructionPacketPath", kind: "required-path" }
|
|
48
|
+
{ name: "workflowInstructionPacketPath", kind: "required-path" },
|
|
49
|
+
{ name: "implementationContextPacketPath", kind: "optional-path" },
|
|
50
|
+
{ name: "implementationContextRetrievalReportPath", kind: "optional-path" },
|
|
51
|
+
{ name: "testContextPacketPath", kind: "optional-path" },
|
|
52
|
+
{ name: "testContextRetrievalReportPath", kind: "optional-path" },
|
|
53
|
+
{ name: "readiness", kind: "optional-object" }
|
|
49
54
|
]
|
|
50
55
|
}
|
|
51
56
|
};
|
|
@@ -93,7 +98,7 @@ export function validateV043StrategyInput(value) {
|
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
100
|
for (const field of contract.fields) {
|
|
96
|
-
if (field.kind !== "optional-path" && root[field.name] === undefined) {
|
|
101
|
+
if (field.kind !== "optional-path" && field.kind !== "optional-object" && root[field.name] === undefined) {
|
|
97
102
|
issues.push({
|
|
98
103
|
code: "MISSING_REQUIRED_FIELD",
|
|
99
104
|
fieldPath: field.name,
|
|
@@ -114,6 +119,15 @@ export function validateV043StrategyInput(value) {
|
|
|
114
119
|
});
|
|
115
120
|
}
|
|
116
121
|
}
|
|
122
|
+
else if (field.kind === "optional-object") {
|
|
123
|
+
if (!isPlainObject(fieldValue)) {
|
|
124
|
+
issues.push({
|
|
125
|
+
code: "INVALID_FIELD_TYPE",
|
|
126
|
+
fieldPath: field.name,
|
|
127
|
+
message: `"${field.name}" must be an object.`
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
117
131
|
else if (typeof fieldValue !== "string") {
|
|
118
132
|
issues.push({
|
|
119
133
|
code: "INVALID_FIELD_TYPE",
|
|
@@ -123,7 +137,7 @@ export function validateV043StrategyInput(value) {
|
|
|
123
137
|
}
|
|
124
138
|
}
|
|
125
139
|
for (const field of contract.fields) {
|
|
126
|
-
if (field.kind === "required-array")
|
|
140
|
+
if (field.kind === "required-array" || field.kind === "optional-object")
|
|
127
141
|
continue;
|
|
128
142
|
const fieldValue = root[field.name];
|
|
129
143
|
if (typeof fieldValue === "string" && fieldValue.length === 0) {
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// v0.4.5 Batch 5: builds the bounded ContextIntegrityReportV1 from already-calculated
|
|
2
|
+
// Batch 1-4 results. Never recalculates allocation, condition coverage, agreement states,
|
|
3
|
+
// hashes, determinism, or immutability -- it only bounds and reshapes values the caller
|
|
4
|
+
// already computed via evaluateProducerReadinessBridge, verifyFixtureHashes, and
|
|
5
|
+
// calculateStageContextDeterminism.
|
|
6
|
+
import { V043_REPORT_DETAIL_LIMIT } from "./contextStrategyComparisonV043ReportModel.js";
|
|
7
|
+
const CORRECTED_REPLAY_LIMITATION = "This corrected-replay fixture is a hand-distilled representation of the exact validated local my-dev-kit v1.10.4 and my-dev-kit-orchestrator v1.2.3 contracts, applied to the same request, target, and active-index identity as the paired failed-run fixture. It is not a live capture of a complete ten-stage AI-authored implementation workflow, and it is not proof that every future run against these contracts will behave identically.";
|
|
8
|
+
function boundItems(source, limit = V043_REPORT_DETAIL_LIMIT) {
|
|
9
|
+
const items = source.slice(0, limit);
|
|
10
|
+
return { totalCount: source.length, displayedCount: items.length, omittedCount: source.length - items.length, items };
|
|
11
|
+
}
|
|
12
|
+
function toContradiction(c) {
|
|
13
|
+
return { code: c.code, fieldPath: c.fieldPath, expected: c.expected, observed: c.observed, reason: c.reason };
|
|
14
|
+
}
|
|
15
|
+
function agreementFromRunIntegrity(component) {
|
|
16
|
+
return {
|
|
17
|
+
availability: component.availability,
|
|
18
|
+
outcome: component.outcome,
|
|
19
|
+
contradictions: boundItems(component.contradictions.map(toContradiction)),
|
|
20
|
+
reason: component.reason
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function unavailableAgreement(reason) {
|
|
24
|
+
return { availability: "unavailable", outcome: "insufficient-evidence", contradictions: boundItems([]), reason };
|
|
25
|
+
}
|
|
26
|
+
export function buildContextIntegrityReport(input) {
|
|
27
|
+
const { manifest, hashVerification, capsule, bridgeResult } = input;
|
|
28
|
+
const side = bridgeResult.implementation ?? bridgeResult.testImplementation;
|
|
29
|
+
const runIntegrity = bridgeResult.runIntegrityEvaluation;
|
|
30
|
+
const derivedCount = manifest.artifacts.filter((a) => a.derived).length;
|
|
31
|
+
const byteExactCount = manifest.artifacts.filter((a) => a.byteExact).length;
|
|
32
|
+
const allocationAgg = side?.groupAllocationEvaluation.aggregate ?? null;
|
|
33
|
+
const spillover = side?.groupAllocationEvaluation.spillover ?? null;
|
|
34
|
+
const conditionCoverage = side?.conditionCoverageEvaluation ?? null;
|
|
35
|
+
const conditionAwareTruncation = side?.conditionAwareTruncationEvaluation ?? null;
|
|
36
|
+
const unavailableSections = [];
|
|
37
|
+
const notes = [];
|
|
38
|
+
if (!side)
|
|
39
|
+
unavailableSections.push("producer");
|
|
40
|
+
if (!runIntegrity)
|
|
41
|
+
unavailableSections.push("run-integrity");
|
|
42
|
+
if (conditionCoverage?.availability !== "available")
|
|
43
|
+
unavailableSections.push("condition-coverage");
|
|
44
|
+
return {
|
|
45
|
+
schemaVersion: "1.0.0",
|
|
46
|
+
detailLimit: V043_REPORT_DETAIL_LIMIT,
|
|
47
|
+
fixture: {
|
|
48
|
+
fixtureId: manifest.fixtureId,
|
|
49
|
+
kind: input.fixtureKind,
|
|
50
|
+
description: manifest.description,
|
|
51
|
+
myDevKitCommit: manifest.myDevKit.commit,
|
|
52
|
+
orchestratorCommit: manifest.orchestrator.commit,
|
|
53
|
+
targetRepositoryIdentity: manifest.targetRepositoryIdentity,
|
|
54
|
+
activeIndexIdentity: manifest.activeIndexIdentity,
|
|
55
|
+
manifestSchemaVersion: manifest.manifestSchemaVersion,
|
|
56
|
+
trackedArtifactCount: manifest.artifacts.length,
|
|
57
|
+
derivedArtifactCount: derivedCount,
|
|
58
|
+
byteExactArtifactCount: byteExactCount,
|
|
59
|
+
artifacts: boundItems(manifest.artifacts.map((a) => ({
|
|
60
|
+
fixtureRelativePath: a.fixtureRelativePath,
|
|
61
|
+
role: a.role,
|
|
62
|
+
derived: a.derived,
|
|
63
|
+
byteExact: a.byteExact,
|
|
64
|
+
provenanceOnly: a.provenanceOnly
|
|
65
|
+
}))),
|
|
66
|
+
hashVerification: {
|
|
67
|
+
ok: hashVerification.ok,
|
|
68
|
+
checkedCount: hashVerification.checkedCount,
|
|
69
|
+
issues: boundItems(hashVerification.issues.map((i) => ({ code: i.code, fixtureRelativePath: i.fixtureRelativePath, message: i.message })))
|
|
70
|
+
},
|
|
71
|
+
correctedReplayLimitation: input.fixtureKind === "corrected-replay" ? CORRECTED_REPLAY_LIMITATION : ""
|
|
72
|
+
},
|
|
73
|
+
producerIdentity: {
|
|
74
|
+
toolName: capsule?.tool.name ?? null,
|
|
75
|
+
toolVersion: capsule?.tool.version ?? null,
|
|
76
|
+
role: capsule?.request.role ?? null,
|
|
77
|
+
projectRoot: capsule?.index.projectRoot ?? null,
|
|
78
|
+
indexPath: capsule?.index.indexPath ?? null,
|
|
79
|
+
roleAdequacyStatus: capsule?.roleAdequacy.status ?? null
|
|
80
|
+
},
|
|
81
|
+
allocation: {
|
|
82
|
+
availability: allocationAgg?.availability ?? "unavailable",
|
|
83
|
+
groupCount: allocationAgg?.groupCount ?? 0,
|
|
84
|
+
totalRequiredOmitted: allocationAgg?.totalRequiredOmitted ?? null,
|
|
85
|
+
totalOptionalOmitted: allocationAgg?.totalOptionalOmitted ?? null,
|
|
86
|
+
aggregateCapacityUsed: null,
|
|
87
|
+
aggregateCapacityRemaining: null,
|
|
88
|
+
groupsWithRequiredOmission: allocationAgg?.groupsWithRequiredOmission ?? [],
|
|
89
|
+
groupsWithOptionalOnlyOmission: allocationAgg?.groupsWithOptionalOnlyOmission ?? [],
|
|
90
|
+
perGroup: boundItems((side?.groupAllocationEvaluation.perGroup ?? []).map((g) => ({
|
|
91
|
+
groupId: g.groupId,
|
|
92
|
+
availability: g.availability,
|
|
93
|
+
required: g.required,
|
|
94
|
+
reservation: g.reservation,
|
|
95
|
+
initiallySelectedCount: g.initiallySelectedCount,
|
|
96
|
+
unusedReservationContributed: g.unusedReservationContributed,
|
|
97
|
+
borrowedCapacity: g.borrowedCapacity,
|
|
98
|
+
requiredOmittedCount: g.requiredOmittedCount,
|
|
99
|
+
optionalOmittedCount: g.optionalOmittedCount,
|
|
100
|
+
adequacyAffected: g.adequacyAffected
|
|
101
|
+
})))
|
|
102
|
+
},
|
|
103
|
+
spillover: {
|
|
104
|
+
availability: spillover?.availability ?? "unavailable",
|
|
105
|
+
groupsContributing: spillover?.groupsContributing ?? [],
|
|
106
|
+
groupsBorrowing: spillover?.groupsBorrowing ?? [],
|
|
107
|
+
totalContributed: spillover?.totalContributed ?? null,
|
|
108
|
+
totalBorrowed: spillover?.totalBorrowed ?? null,
|
|
109
|
+
contributionCoversBorrowing: spillover?.contributionCoversBorrowing ?? null,
|
|
110
|
+
reason: spillover?.reason ?? null
|
|
111
|
+
},
|
|
112
|
+
truncation: {
|
|
113
|
+
availability: conditionAwareTruncation?.availability ?? "unavailable",
|
|
114
|
+
state: conditionAwareTruncation?.state ?? "unsupported-legacy-diagnostics",
|
|
115
|
+
requiredEvidenceLost: conditionAwareTruncation?.requiredEvidenceLost ?? null,
|
|
116
|
+
requiredOmittedTotal: conditionAwareTruncation?.requiredOmittedTotal ?? null,
|
|
117
|
+
optionalOmittedTotal: conditionAwareTruncation?.optionalOmittedTotal ?? null,
|
|
118
|
+
lostRequiredConditionIds: conditionAwareTruncation?.lostRequiredConditionIds ?? [],
|
|
119
|
+
contradictions: boundItems((conditionAwareTruncation?.contradictionCodes ?? []).map((code) => ({ code, fieldPath: "truncation", expected: null, observed: null, reason: conditionAwareTruncation?.reason ?? "" })))
|
|
120
|
+
},
|
|
121
|
+
conditionCoverage: {
|
|
122
|
+
availability: conditionCoverage?.availability ?? "unavailable",
|
|
123
|
+
requiredConditionsTotal: conditionCoverage?.requiredConditionsTotal.count ?? null,
|
|
124
|
+
requiredConditionsSatisfied: conditionCoverage?.requiredConditionsSatisfied.count ?? null,
|
|
125
|
+
requiredConditionsMissing: conditionCoverage?.requiredConditionsMissing.evidenceKeys ?? [],
|
|
126
|
+
requiredConditionsLost: conditionCoverage?.requiredConditionsLost.evidenceKeys ?? [],
|
|
127
|
+
lastWitnessLossCount: conditionCoverage?.lastWitnessLoss.count ?? null,
|
|
128
|
+
witnessEvidence: boundItems((conditionCoverage?.witnessEvidence ?? []).map((w) => ({
|
|
129
|
+
conditionId: w.conditionId,
|
|
130
|
+
required: w.required,
|
|
131
|
+
coverageState: w.coverageState,
|
|
132
|
+
retainedWitnessCount: w.retainedWitnessCount,
|
|
133
|
+
retainedWitnessIds: boundItems(w.retainedWitnessIds),
|
|
134
|
+
adequateWitnessRemains: w.adequateWitnessRemains,
|
|
135
|
+
lossReason: w.lossReason,
|
|
136
|
+
evidenceGroupIds: w.evidenceGroupIds
|
|
137
|
+
}))),
|
|
138
|
+
reason: conditionCoverage?.reason ?? null
|
|
139
|
+
},
|
|
140
|
+
producerConditionAgreement: side
|
|
141
|
+
? {
|
|
142
|
+
availability: side.producerConditionAgreement.availability,
|
|
143
|
+
outcome: side.producerConditionAgreement.outcome,
|
|
144
|
+
contradictions: boundItems(side.producerConditionAgreement.contradictionCodes.map((code) => ({ code, fieldPath: "roleAdequacy", expected: null, observed: null, reason: side.producerConditionAgreement.reason ?? "" }))),
|
|
145
|
+
reason: side.producerConditionAgreement.reason
|
|
146
|
+
}
|
|
147
|
+
: unavailableAgreement("No producer side was supplied."),
|
|
148
|
+
requiredEvidenceLossAgreement: side
|
|
149
|
+
? {
|
|
150
|
+
availability: side.requiredEvidenceLossAgreement.availability,
|
|
151
|
+
outcome: side.requiredEvidenceLossAgreement.outcome,
|
|
152
|
+
contradictions: boundItems(side.requiredEvidenceLossAgreement.contradictionCodes.map((code) => ({ code, fieldPath: "truncation.requiredEvidenceLost", expected: null, observed: null, reason: side.requiredEvidenceLossAgreement.reason ?? "" }))),
|
|
153
|
+
reason: side.requiredEvidenceLossAgreement.reason
|
|
154
|
+
}
|
|
155
|
+
: unavailableAgreement("No producer side was supplied."),
|
|
156
|
+
capsuleAuditAgreement: side
|
|
157
|
+
? {
|
|
158
|
+
availability: side.capsuleAuditConditionAgreement.availability,
|
|
159
|
+
consistent: side.capsuleAuditConditionAgreement.consistent,
|
|
160
|
+
contradictingFieldPaths: side.capsuleAuditConditionAgreement.contradictingFieldPaths
|
|
161
|
+
}
|
|
162
|
+
: { availability: "unavailable", consistent: null, contradictingFieldPaths: [] },
|
|
163
|
+
supplementalRawAgreement: side?.packetAgreement || side?.reportAgreement
|
|
164
|
+
? {
|
|
165
|
+
availability: "available",
|
|
166
|
+
contradictingFields: [...(side.packetAgreement?.contradictions ?? []), ...(side.reportAgreement?.contradictions ?? [])].map((f) => f.field),
|
|
167
|
+
upstreamProducerParityPreserved: side.packetAgreement?.upstreamProducerParityPreserved ?? side.reportAgreement?.upstreamProducerParityPreserved ?? null
|
|
168
|
+
}
|
|
169
|
+
: null,
|
|
170
|
+
producerReadinessAgreement: bridgeResult.producerReadinessRelationship
|
|
171
|
+
? {
|
|
172
|
+
availability: bridgeResult.producerReadinessRelationship.availability,
|
|
173
|
+
outcome: bridgeResult.producerReadinessRelationship.outcome,
|
|
174
|
+
contradictions: boundItems(bridgeResult.producerReadinessRelationship.contradictionCodes.map((code) => ({ code, fieldPath: "readiness", expected: null, observed: null, reason: bridgeResult.producerReadinessRelationship.reason ?? "" }))),
|
|
175
|
+
reason: bridgeResult.producerReadinessRelationship.reason
|
|
176
|
+
}
|
|
177
|
+
: unavailableAgreement("No producer/readiness relationship was calculated."),
|
|
178
|
+
readinessPromptAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.readinessPrompt) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
179
|
+
readinessExpectedJudgeAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.readinessExpectedJudge) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
180
|
+
expectedActualJudgeAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.expectedActualJudge) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
181
|
+
judgeCorrectionAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.judgeCorrection) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
182
|
+
judgeFinalEligibilityAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.judgeFinalEligibility) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
183
|
+
eligibilityFinalArtifactAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.eligibilityFinalArtifact) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
184
|
+
lifecycleIntegrityAgreement: runIntegrity ? agreementFromRunIntegrity(runIntegrity.lifecycleIntegrity) : unavailableAgreement("No run-integrity evidence was supplied."),
|
|
185
|
+
endToEnd: runIntegrity
|
|
186
|
+
? { category: runIntegrity.endToEndSummary.category, componentOutcomes: runIntegrity.endToEndSummary.componentOutcomes, contradictingComponents: runIntegrity.endToEndSummary.contradictingComponents }
|
|
187
|
+
: null,
|
|
188
|
+
determinism: input.determinism
|
|
189
|
+
? {
|
|
190
|
+
availability: input.determinism.availability,
|
|
191
|
+
repeatCount: input.determinism.repeatCount,
|
|
192
|
+
deterministic: input.determinism.deterministic,
|
|
193
|
+
baselineSha256: input.determinism.baselineSha256,
|
|
194
|
+
mismatchRunNumbers: input.determinism.mismatchRunNumbers,
|
|
195
|
+
reason: input.determinism.reason
|
|
196
|
+
}
|
|
197
|
+
: { availability: "not-applicable", repeatCount: 1, deterministic: null, baselineSha256: null, mismatchRunNumbers: [], reason: "Determinism was not evaluated for this report." },
|
|
198
|
+
immutability: {
|
|
199
|
+
fixtureSelfImmutable: input.fixtureSelfImmutable ?? null,
|
|
200
|
+
fixtureImmutabilityReason: input.fixtureSelfImmutableReason ?? (input.fixtureSelfImmutable === undefined ? "Fixture self-immutability was not checked for this report." : null)
|
|
201
|
+
},
|
|
202
|
+
limitations: { unavailableSections, notes }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
@@ -69,12 +69,134 @@ function buildSummary(executions, evaluations, assurances) {
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
function buildStrategyReport(execution, evaluation, assurance) {
|
|
72
|
+
const producerReadinessBridge = buildProducerReadinessBridgeReport(assurance.primaryProducerReadinessBridge);
|
|
72
73
|
return {
|
|
73
74
|
strategyId: assurance.strategyId,
|
|
74
75
|
artifacts: buildArtifactMetadata(execution),
|
|
75
76
|
execution: buildExecutionSummary(execution),
|
|
76
77
|
evaluation: buildEvaluationSummary(evaluation),
|
|
77
78
|
assurance: buildAssuranceSummary(assurance),
|
|
79
|
+
...(producerReadinessBridge ? { producerReadinessBridge } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function buildAllocationFactList(source) {
|
|
83
|
+
return boundItems(source.map((f) => ({ groupId: f.groupId, value: f.value, unit: f.unit, availability: f.availability, reason: f.reason })));
|
|
84
|
+
}
|
|
85
|
+
function buildOwnerEvaluation(owner) {
|
|
86
|
+
return {
|
|
87
|
+
selectedOwnerEvidence: boundItems(owner.selectedOwnerEvidence.map((e) => ({ ownerId: e.ownerId, sourceArtifact: e.sourceArtifact, sourceInstance: e.sourceInstance }))),
|
|
88
|
+
expectedOwnerPresent: buildRatioMetric(owner.expectedOwnerPresent),
|
|
89
|
+
forbiddenOwnerPresent: buildRatioMetric(owner.forbiddenOwnerPresent),
|
|
90
|
+
falsePositiveCount: buildCountMetric(owner.falsePositiveCount),
|
|
91
|
+
falseNegativeCount: buildCountMetric(owner.falseNegativeCount),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function buildTruncationList(source) {
|
|
95
|
+
return boundItems(source.map((t) => ({
|
|
96
|
+
groupId: t.groupId,
|
|
97
|
+
cause: t.cause,
|
|
98
|
+
availability: t.availability,
|
|
99
|
+
reason: t.reason,
|
|
100
|
+
omittedRequiredEvidenceIds: t.omittedRequiredEvidenceIds,
|
|
101
|
+
limit: t.limit,
|
|
102
|
+
used: t.used,
|
|
103
|
+
available: t.available,
|
|
104
|
+
})));
|
|
105
|
+
}
|
|
106
|
+
function buildSupplementalRawAgreement(agreement) {
|
|
107
|
+
if (agreement === null)
|
|
108
|
+
return null;
|
|
109
|
+
return {
|
|
110
|
+
fields: agreement.fields.map((f) => ({ field: f.field, rawValue: f.rawValue, supplementalValue: f.supplementalValue, agreement: f.agreement, availability: f.availability, reason: f.reason })),
|
|
111
|
+
contradictions: agreement.contradictions.map((f) => ({ field: f.field, rawValue: f.rawValue, supplementalValue: f.supplementalValue, agreement: f.agreement, availability: f.availability, reason: f.reason })),
|
|
112
|
+
upstreamProducerParityPreserved: agreement.upstreamProducerParityPreserved,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function buildProducerReadinessSide(side) {
|
|
116
|
+
return {
|
|
117
|
+
role: side.role,
|
|
118
|
+
ownerEvaluation: buildOwnerEvaluation(side.ownerEvaluation),
|
|
119
|
+
allocationEvaluation: {
|
|
120
|
+
requiredGroupCapacity: buildAllocationFactList(side.allocationEvaluation.requiredGroupCapacity),
|
|
121
|
+
usedReservation: buildAllocationFactList(side.allocationEvaluation.usedReservation),
|
|
122
|
+
borrowedCapacity: buildAllocationFactList(side.allocationEvaluation.borrowedCapacity),
|
|
123
|
+
unusedCapacity: buildAllocationFactList(side.allocationEvaluation.unusedCapacity),
|
|
124
|
+
},
|
|
125
|
+
truncationEvaluation: buildTruncationList(side.truncationEvaluation),
|
|
126
|
+
packetAgreement: buildSupplementalRawAgreement(side.packetAgreement),
|
|
127
|
+
reportAgreement: buildSupplementalRawAgreement(side.reportAgreement),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function buildReadinessAgreement(agreement) {
|
|
131
|
+
return {
|
|
132
|
+
structuralAgreement: agreement.structuralAgreement.map((s) => ({
|
|
133
|
+
field: s.field,
|
|
134
|
+
expectedValue: s.expectedValue,
|
|
135
|
+
observedValue: s.observedValue,
|
|
136
|
+
agreement: s.agreement,
|
|
137
|
+
availability: s.availability,
|
|
138
|
+
reason: s.reason,
|
|
139
|
+
})),
|
|
140
|
+
decisionAgreement: {
|
|
141
|
+
availability: agreement.decisionAgreement.availability,
|
|
142
|
+
observedDecision: agreement.decisionAgreement.observedDecision,
|
|
143
|
+
allowedDecisions: agreement.decisionAgreement.allowedDecisions,
|
|
144
|
+
decisionAgreement: agreement.decisionAgreement.decisionAgreement,
|
|
145
|
+
observedIssueCodes: agreement.decisionAgreement.observedIssueCodes,
|
|
146
|
+
expectedIssueCodes: agreement.decisionAgreement.expectedIssueCodes,
|
|
147
|
+
issueCodesAgreement: agreement.decisionAgreement.issueCodesAgreement,
|
|
148
|
+
observedPrimaryIssueCode: agreement.decisionAgreement.observedPrimaryIssueCode,
|
|
149
|
+
expectedPrimaryIssueCode: agreement.decisionAgreement.expectedPrimaryIssueCode,
|
|
150
|
+
primaryIssueAgreement: agreement.decisionAgreement.primaryIssueAgreement,
|
|
151
|
+
reason: agreement.decisionAgreement.reason,
|
|
152
|
+
},
|
|
153
|
+
invalidReady: {
|
|
154
|
+
availability: agreement.invalidReady.availability,
|
|
155
|
+
invalidReady: agreement.invalidReady.invalidReady,
|
|
156
|
+
missingExpectedIssueCodes: agreement.invalidReady.missingExpectedIssueCodes,
|
|
157
|
+
reason: agreement.invalidReady.reason,
|
|
158
|
+
},
|
|
159
|
+
validBlocked: {
|
|
160
|
+
availability: agreement.validBlocked.availability,
|
|
161
|
+
validBlocked: agreement.validBlocked.validBlocked,
|
|
162
|
+
validRefreshRequired: agreement.validBlocked.validRefreshRequired,
|
|
163
|
+
observedDecision: agreement.validBlocked.observedDecision,
|
|
164
|
+
reason: agreement.validBlocked.reason,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function buildCriticalityEvaluation(criticality) {
|
|
169
|
+
return {
|
|
170
|
+
overlayAgreement: boundItems(criticality.overlayAgreement.map((e) => ({
|
|
171
|
+
responsibilityId: e.responsibilityId,
|
|
172
|
+
expectedCriticality: e.expectedCriticality,
|
|
173
|
+
observedCriticality: e.observedCriticality,
|
|
174
|
+
agreement: e.agreement,
|
|
175
|
+
availability: e.availability,
|
|
176
|
+
reason: e.reason,
|
|
177
|
+
}))),
|
|
178
|
+
missingCriticalityResponsibilityIds: criticality.missingCriticalityResponsibilityIds,
|
|
179
|
+
conflictingCriticalityResponsibilityIds: criticality.conflictingCriticalityResponsibilityIds,
|
|
180
|
+
unexpectedCriticalityResponsibilityIds: criticality.unexpectedCriticalityResponsibilityIds,
|
|
181
|
+
mappedCriticalCompleteness: buildRatioMetric(criticality.mappedCriticalCompleteness),
|
|
182
|
+
fullyMappedCriticalIds: criticality.fullyMappedCriticalIds,
|
|
183
|
+
partiallyMappedCriticalIds: criticality.partiallyMappedCriticalIds,
|
|
184
|
+
unmappedCriticalIds: criticality.unmappedCriticalIds,
|
|
185
|
+
missingMappingEvidenceCriticalIds: criticality.missingMappingEvidenceCriticalIds,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function buildProducerReadinessBridgeReport(bridge) {
|
|
189
|
+
if (bridge === null || bridge === undefined)
|
|
190
|
+
return null;
|
|
191
|
+
return {
|
|
192
|
+
status: bridge.status,
|
|
193
|
+
reason: bridge.reason,
|
|
194
|
+
implementation: bridge.implementation ? buildProducerReadinessSide(bridge.implementation) : null,
|
|
195
|
+
testImplementation: bridge.testImplementation ? buildProducerReadinessSide(bridge.testImplementation) : null,
|
|
196
|
+
readinessAgreement: bridge.readinessAgreement ? buildReadinessAgreement(bridge.readinessAgreement) : null,
|
|
197
|
+
criticalityEvaluation: bridge.criticalityEvaluation ? buildCriticalityEvaluation(bridge.criticalityEvaluation) : null,
|
|
198
|
+
warnings: boundItems(bridge.warnings),
|
|
199
|
+
evidenceReferences: boundItems(bridge.evidenceReferences),
|
|
78
200
|
};
|
|
79
201
|
}
|
|
80
202
|
function buildExecutionSummary(execution) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -6,3 +6,8 @@ export * from "./contextStrategyComparisonV043ReportModel.js";
|
|
|
6
6
|
export { buildContextStrategyComparisonV043Report } from "./buildContextStrategyComparisonV043Report.js";
|
|
7
7
|
export { renderContextStrategyComparisonV043Html } from "./renderContextStrategyComparisonV043Html.js";
|
|
8
8
|
export { renderPluginExperimentReportText } from "./renderPluginExperimentReportText.js";
|
|
9
|
+
export * from "./contextIntegrityReportModel.js";
|
|
10
|
+
export { buildContextIntegrityReport } from "./buildContextIntegrityReport.js";
|
|
11
|
+
export { renderContextIntegrityJsonReport } from "./renderContextIntegrityJsonReport.js";
|
|
12
|
+
export { renderContextIntegrityText } from "./renderContextIntegrityText.js";
|
|
13
|
+
export { renderContextIntegrityHtml } from "./renderContextIntegrityHtml.js";
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
function escapeHtml(value) {
|
|
2
|
+
return String(value ?? "")
|
|
3
|
+
.replaceAll("&", "&")
|
|
4
|
+
.replaceAll("<", "<")
|
|
5
|
+
.replaceAll(">", ">")
|
|
6
|
+
.replaceAll('"', """)
|
|
7
|
+
.replaceAll("'", "'");
|
|
8
|
+
}
|
|
9
|
+
function table(headers, rows) {
|
|
10
|
+
return `<table><thead><tr>${headers.map((h) => `<th>${escapeHtml(h)}</th>`).join("")}</tr></thead><tbody>${rows
|
|
11
|
+
.map((row) => `<tr>${row.map((cell) => `<td>${escapeHtml(cell)}</td>`).join("")}</tr>`)
|
|
12
|
+
.join("")}</tbody></table>`;
|
|
13
|
+
}
|
|
14
|
+
function renderAgreementSection(label, agreement) {
|
|
15
|
+
const rows = agreement.contradictions.items.map((c) => [c.code, c.fieldPath, c.expected ?? "", c.observed ?? "", c.reason]);
|
|
16
|
+
return `<section><h3>${escapeHtml(label)}</h3>${table(["Availability", "Outcome", "Reason"], [[agreement.availability, agreement.outcome, agreement.reason ?? ""]])}${agreement.contradictions.totalCount > 0
|
|
17
|
+
? `<p class="muted">Contradictions displayed ${agreement.contradictions.displayedCount} of ${agreement.contradictions.totalCount} (omitted ${agreement.contradictions.omittedCount}).</p>${table(["Code", "Field path", "Expected", "Observed", "Reason"], rows)}`
|
|
18
|
+
: ""}</section>`;
|
|
19
|
+
}
|
|
20
|
+
export function renderContextIntegrityHtml(report) {
|
|
21
|
+
const endToEndLabel = report.endToEnd?.category ?? "unavailable";
|
|
22
|
+
return `<!doctype html>
|
|
23
|
+
<html lang="en">
|
|
24
|
+
<head>
|
|
25
|
+
<meta charset="utf-8" />
|
|
26
|
+
<title>Context-integrity report: ${escapeHtml(report.fixture.fixtureId)}</title>
|
|
27
|
+
<style>
|
|
28
|
+
body { font-family: system-ui, sans-serif; margin: 2rem; color: #1a1a1a; }
|
|
29
|
+
table { border-collapse: collapse; margin: 0.5rem 0 1rem; width: 100%; }
|
|
30
|
+
th, td { border: 1px solid #ccc; padding: 0.35rem 0.5rem; text-align: left; font-size: 0.9rem; }
|
|
31
|
+
.muted { color: #666; font-size: 0.85rem; }
|
|
32
|
+
.badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 0.25rem; font-weight: 600; }
|
|
33
|
+
.badge-full-agreement { background: #d7f5dd; color: #1b6b32; }
|
|
34
|
+
.badge-contradiction-present { background: #fbdada; color: #8f1d1d; }
|
|
35
|
+
.badge-insufficient-evidence, .badge-unsupported-legacy-evidence { background: #eee; color: #444; }
|
|
36
|
+
section { margin-bottom: 1.5rem; }
|
|
37
|
+
</style>
|
|
38
|
+
</head>
|
|
39
|
+
<body>
|
|
40
|
+
<h1>Context-integrity report: ${escapeHtml(report.fixture.fixtureId)} (${escapeHtml(report.fixture.kind)})</h1>
|
|
41
|
+
<p>End-to-end result: <span class="badge badge-${escapeHtml(endToEndLabel)}">${escapeHtml(endToEndLabel)}</span></p>
|
|
42
|
+
${report.fixture.correctedReplayLimitation ? `<p class="muted"><strong>Limitation:</strong> ${escapeHtml(report.fixture.correctedReplayLimitation)}</p>` : ""}
|
|
43
|
+
|
|
44
|
+
<section><h2>Fixture and provenance</h2>${table(["Field", "Value"], [
|
|
45
|
+
["my-dev-kit commit", report.fixture.myDevKitCommit ?? ""],
|
|
46
|
+
["orchestrator commit", report.fixture.orchestratorCommit ?? ""],
|
|
47
|
+
["Target repository identity", report.fixture.targetRepositoryIdentity ?? ""],
|
|
48
|
+
["Active index identity", report.fixture.activeIndexIdentity ?? ""],
|
|
49
|
+
["Tracked artifacts", String(report.fixture.trackedArtifactCount)],
|
|
50
|
+
["Derived artifacts", String(report.fixture.derivedArtifactCount)],
|
|
51
|
+
["Byte-exact artifacts", String(report.fixture.byteExactArtifactCount)],
|
|
52
|
+
["Hash verification", report.fixture.hashVerification.ok ? "PASS" : "FAIL"]
|
|
53
|
+
])}</section>
|
|
54
|
+
|
|
55
|
+
<section><h2>Producer allocation and omissions</h2>${table(["Field", "Value"], [
|
|
56
|
+
["Role adequacy status", report.producerIdentity.roleAdequacyStatus ?? "(unavailable)"],
|
|
57
|
+
["Groups evaluated", String(report.allocation.groupCount)],
|
|
58
|
+
["Total required omitted", String(report.allocation.totalRequiredOmitted ?? "(unavailable)")],
|
|
59
|
+
["Total optional omitted", String(report.allocation.totalOptionalOmitted ?? "(unavailable)")],
|
|
60
|
+
["Groups with required omission", report.allocation.groupsWithRequiredOmission.join(", ") || "(none)"],
|
|
61
|
+
["Groups with optional-only omission", report.allocation.groupsWithOptionalOnlyOmission.join(", ") || "(none)"],
|
|
62
|
+
["Truncation state", report.truncation.state],
|
|
63
|
+
["requiredEvidenceLost", String(report.truncation.requiredEvidenceLost)]
|
|
64
|
+
])}</section>
|
|
65
|
+
|
|
66
|
+
<section><h2>Condition coverage</h2>${table(["Field", "Value"], [
|
|
67
|
+
["Availability", report.conditionCoverage.availability],
|
|
68
|
+
["Required conditions total", String(report.conditionCoverage.requiredConditionsTotal ?? "(unavailable)")],
|
|
69
|
+
["Required conditions satisfied", String(report.conditionCoverage.requiredConditionsSatisfied ?? "(unavailable)")],
|
|
70
|
+
["Required conditions missing", report.conditionCoverage.requiredConditionsMissing.join(", ") || "(none)"],
|
|
71
|
+
["Required conditions lost", report.conditionCoverage.requiredConditionsLost.join(", ") || "(none)"],
|
|
72
|
+
["Last-witness-loss count", String(report.conditionCoverage.lastWitnessLossCount ?? "(unavailable)")]
|
|
73
|
+
])}</section>
|
|
74
|
+
|
|
75
|
+
${renderAgreementSection("Producer-condition agreement", report.producerConditionAgreement)}
|
|
76
|
+
${renderAgreementSection("requiredEvidenceLost agreement", report.requiredEvidenceLossAgreement)}
|
|
77
|
+
${renderAgreementSection("Producer/readiness relationship", report.producerReadinessAgreement)}
|
|
78
|
+
<p class="muted">Note: the orchestrator does not expose a literal upstream <code>promptMode</code> field. <code>stageMayRenderNormalPrompt</code> (derived from structured blocked-stage evidence) is the bounded substitute used below.</p>
|
|
79
|
+
${renderAgreementSection("Readiness/prompt agreement", report.readinessPromptAgreement)}
|
|
80
|
+
${renderAgreementSection("Readiness/expected-judge agreement", report.readinessExpectedJudgeAgreement)}
|
|
81
|
+
${renderAgreementSection("Expected/actual-judge agreement", report.expectedActualJudgeAgreement)}
|
|
82
|
+
${renderAgreementSection("Judge/correction agreement", report.judgeCorrectionAgreement)}
|
|
83
|
+
${renderAgreementSection("Judge/final-eligibility agreement", report.judgeFinalEligibilityAgreement)}
|
|
84
|
+
${renderAgreementSection("Eligibility/final-artifact agreement", report.eligibilityFinalArtifactAgreement)}
|
|
85
|
+
${renderAgreementSection("Lifecycle-integrity agreement", report.lifecycleIntegrityAgreement)}
|
|
86
|
+
|
|
87
|
+
<section><h2>Determinism and immutability</h2>${table(["Field", "Value"], [
|
|
88
|
+
["Determinism availability", report.determinism.availability],
|
|
89
|
+
["Repeat count", String(report.determinism.repeatCount)],
|
|
90
|
+
["Deterministic", String(report.determinism.deterministic)],
|
|
91
|
+
["Fixture self-immutable", String(report.immutability.fixtureSelfImmutable)]
|
|
92
|
+
])}</section>
|
|
93
|
+
|
|
94
|
+
<section><h2>Limitations</h2>${report.limitations.notes.length > 0 ? `<ul>${report.limitations.notes.map((n) => `<li>${escapeHtml(n)}</li>`).join("")}</ul>` : "<p>(none)</p>"}</section>
|
|
95
|
+
</body>
|
|
96
|
+
</html>
|
|
97
|
+
`;
|
|
98
|
+
}
|