@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.
Files changed (97) hide show
  1. package/CHANGELOG.md +468 -0
  2. package/README.md +8 -1
  3. package/dist/scripts/report-context-integrity-smoke.js +70 -0
  4. package/dist/src/evaluation/ecosystemFixtures/index.js +3 -0
  5. package/dist/src/evaluation/ecosystemFixtures/loadContextIntegrityFixture.js +102 -0
  6. package/dist/src/evaluation/ecosystemFixtures/manifestTypes.js +1 -0
  7. package/dist/src/evaluation/ecosystemFixtures/validateManifest.js +82 -0
  8. package/dist/src/evaluation/ecosystemFixtures/verifyFixtureHashes.js +45 -0
  9. package/dist/src/evaluation/stageContextExpectations/producerReadinessExpectationTypes.js +8 -0
  10. package/dist/src/evaluation/stageContextExpectations/validation.js +200 -0
  11. package/dist/src/evaluation/stageContextMetrics/calculateAllocationMetrics.js +265 -0
  12. package/dist/src/evaluation/stageContextMetrics/calculateConditionCoverageMetrics.js +74 -0
  13. package/dist/src/evaluation/stageContextMetrics/calculateCriticalityMetrics.js +112 -0
  14. package/dist/src/evaluation/stageContextMetrics/calculateOwnerMetrics.js +84 -0
  15. package/dist/src/evaluation/stageContextMetrics/calculateProducerConditionAgreement.js +113 -0
  16. package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +212 -0
  17. package/dist/src/evaluation/stageContextMetrics/calculateRunIntegrityAgreement.js +309 -0
  18. package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +60 -0
  19. package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +144 -0
  20. package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +198 -0
  21. package/dist/src/evaluation/stageContextMetrics/index.js +11 -0
  22. package/dist/src/evaluation/stageContextMetrics/producerReadinessMetricTypes.js +1 -0
  23. package/dist/src/evaluation/stageContextMetrics/runIntegrityAgreementTypes.js +1 -0
  24. package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +17 -0
  25. package/dist/src/evaluation/stageContextSelectors/index.js +1 -0
  26. package/dist/src/evaluation/stageContextSelectors/orchestratorRunIntegritySelectors.js +64 -0
  27. package/dist/src/evaluation/upstreamArtifacts/index.js +8 -0
  28. package/dist/src/evaluation/upstreamArtifacts/orchestratorContextReadinessResultV1.js +247 -0
  29. package/dist/src/evaluation/upstreamArtifacts/orchestratorRunIntegrityV1.js +33 -0
  30. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextPacketV1.js +9 -0
  31. package/dist/src/evaluation/upstreamArtifacts/readImplementationContextRetrievalReportV1.js +9 -0
  32. package/dist/src/evaluation/upstreamArtifacts/readOrchestratorRunIntegrityV1.js +9 -0
  33. package/dist/src/evaluation/upstreamArtifacts/readSupplementalContextTextFile.js +29 -0
  34. package/dist/src/evaluation/upstreamArtifacts/readTestContextPacketV1.js +9 -0
  35. package/dist/src/evaluation/upstreamArtifacts/readTestContextRetrievalReportV1.js +9 -0
  36. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTextParser.js +75 -0
  37. package/dist/src/evaluation/upstreamArtifacts/supplementalContextTypes.js +152 -0
  38. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +59 -2
  39. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +15 -3
  40. package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorRunIntegrityV1.js +177 -0
  41. package/dist/src/evaluation/upstreamArtifacts/validateSupplementalContextDocumentV1.js +148 -0
  42. package/dist/src/experiments/plugins/contextStrategyComparison/loadV043StrategyArtifacts.js +117 -6
  43. package/dist/src/experiments/plugins/contextStrategyComparison/runV043StageContextStrategyWithAssurance.js +18 -3
  44. package/dist/src/experiments/plugins/contextStrategyComparison/validateV043StrategyInput.js +17 -3
  45. package/dist/src/report/experiments/buildContextIntegrityReport.js +204 -0
  46. package/dist/src/report/experiments/buildContextStrategyComparisonV043Report.js +122 -0
  47. package/dist/src/report/experiments/contextIntegrityReportModel.js +1 -0
  48. package/dist/src/report/experiments/index.js +5 -0
  49. package/dist/src/report/experiments/renderContextIntegrityHtml.js +98 -0
  50. package/dist/src/report/experiments/renderContextIntegrityJsonReport.js +3 -0
  51. package/dist/src/report/experiments/renderContextIntegrityText.js +111 -0
  52. package/dist/src/report/experiments/renderContextStrategyComparisonV043Html.js +62 -0
  53. package/dist/src/report/experiments/renderPluginExperimentReportText.js +67 -0
  54. package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +33 -0
  55. package/dist/src/securityValidation/packageChecks/runPackageChecks.js +11 -5
  56. package/docs/METRICS.md +111 -0
  57. package/package.json +5 -3
  58. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/derived/run-integrity-evidence.json +99 -0
  59. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-audit.json +1585 -0
  60. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-capsule.json +11455 -0
  61. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/00-request.txt +1 -0
  62. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/architecture-context-packet.txt +82 -0
  63. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/behavior-model.txt +104 -0
  64. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/final-report.txt +41 -0
  65. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-context-packet.txt +114 -0
  66. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-report.txt +92 -0
  67. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/judge-report.txt +34 -0
  68. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/pseudocode-packet.txt +244 -0
  69. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/request-brief.txt +40 -0
  70. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-context-packet.txt +93 -0
  71. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-implementation-report.txt +69 -0
  72. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-strategy-packet.txt +354 -0
  73. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/verification-report.txt +85 -0
  74. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/derived/run-integrity-evidence.json +98 -0
  75. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-audit.json +1169 -0
  76. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-request.json +29 -0
  77. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-audit.json +1494 -0
  78. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-capsule.json +11364 -0
  79. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-request.json +33 -0
  80. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/test-request.json +74 -0
  81. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/architecture-context-retrieval-report.txt +58 -0
  82. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/implementation-context-retrieval-report.txt +75 -0
  83. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/test-context-retrieval-report.txt +84 -0
  84. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/run.json +62 -0
  85. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/my-dev-kit-version.txt +1 -0
  86. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/orchestrator-version.txt +1 -0
  87. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/corrected-replay-manifest.json +19 -0
  88. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/failed-run-manifest.json +56 -0
  89. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/PROVENANCE.txt +18 -0
  90. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/context-capsule/complete-v1.0.0.json +556 -0
  91. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/retrieval-audit-record/complete-v1.0.0.json +238 -0
  92. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +13 -0
  93. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +7874 -0
  94. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +1076 -0
  95. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/PROVENANCE.txt +31 -0
  96. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/ready-pass-final-pass.json +132 -0
  97. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/refresh-required-need-context.json +146 -0
@@ -0,0 +1,111 @@
1
+ function line(label, value) {
2
+ return ` ${label}: ${value === null || value === undefined ? "(unavailable)" : String(value)}`;
3
+ }
4
+ function renderAgreement(label, agreement) {
5
+ const lines = [`${label}: ${agreement.outcome} (availability: ${agreement.availability})`];
6
+ if (agreement.reason)
7
+ lines.push(` reason: ${agreement.reason}`);
8
+ if (agreement.contradictions.totalCount > 0) {
9
+ lines.push(` contradictions (${agreement.contradictions.displayedCount} of ${agreement.contradictions.totalCount}, omitted ${agreement.contradictions.omittedCount}):`);
10
+ for (const c of agreement.contradictions.items) {
11
+ lines.push(` - [${c.code}] ${c.fieldPath}: expected=${c.expected ?? "(n/a)"} observed=${c.observed ?? "(n/a)"} -- ${c.reason}`);
12
+ }
13
+ }
14
+ return lines.join("\n");
15
+ }
16
+ export function renderContextIntegrityText(report) {
17
+ const sections = [];
18
+ sections.push([
19
+ "=== 1. Context-integrity summary ===",
20
+ line("Fixture ID", report.fixture.fixtureId),
21
+ line("Fixture kind", report.fixture.kind),
22
+ line("End-to-end category", report.endToEnd?.category ?? "(unavailable)"),
23
+ line("Contradicting components", report.endToEnd ? report.endToEnd.contradictingComponents.join(", ") || "(none)" : "(unavailable)")
24
+ ].join("\n"));
25
+ sections.push([
26
+ "=== 2. Fixture and provenance ===",
27
+ line("Description", report.fixture.description),
28
+ line("my-dev-kit commit", report.fixture.myDevKitCommit),
29
+ line("orchestrator commit", report.fixture.orchestratorCommit),
30
+ line("Target repository identity", report.fixture.targetRepositoryIdentity),
31
+ line("Active index identity", report.fixture.activeIndexIdentity),
32
+ line("Manifest schema version", report.fixture.manifestSchemaVersion),
33
+ line("Tracked artifacts", report.fixture.trackedArtifactCount),
34
+ line("Derived artifacts", report.fixture.derivedArtifactCount),
35
+ line("Byte-exact artifacts", report.fixture.byteExactArtifactCount),
36
+ line("Hash verification", `${report.fixture.hashVerification.ok ? "PASS" : "FAIL"} (${report.fixture.hashVerification.checkedCount} checked)`),
37
+ ...(report.fixture.correctedReplayLimitation ? [` LIMITATION: ${report.fixture.correctedReplayLimitation}`] : [])
38
+ ].join("\n"));
39
+ sections.push([
40
+ "=== 3. Producer allocation and omissions ===",
41
+ line("Producer tool", `${report.producerIdentity.toolName ?? "(unavailable)"} ${report.producerIdentity.toolVersion ?? ""}`.trim()),
42
+ line("Role adequacy status", report.producerIdentity.roleAdequacyStatus),
43
+ line("Allocation availability", report.allocation.availability),
44
+ line("Groups evaluated", report.allocation.groupCount),
45
+ line("Total required omitted", report.allocation.totalRequiredOmitted),
46
+ line("Total optional omitted", report.allocation.totalOptionalOmitted),
47
+ line("Groups with required omission", report.allocation.groupsWithRequiredOmission.join(", ") || "(none)"),
48
+ line("Groups with optional-only omission", report.allocation.groupsWithOptionalOnlyOmission.join(", ") || "(none)"),
49
+ line("Spillover availability", report.spillover.availability),
50
+ line("Groups contributing capacity", report.spillover.groupsContributing.join(", ") || "(none)"),
51
+ line("Groups borrowing capacity", report.spillover.groupsBorrowing.join(", ") || "(none)"),
52
+ line("Truncation state", report.truncation.state),
53
+ line("requiredEvidenceLost", report.truncation.requiredEvidenceLost)
54
+ ].join("\n"));
55
+ sections.push([
56
+ "=== 4. Condition coverage ===",
57
+ line("Availability", report.conditionCoverage.availability),
58
+ line("Required conditions total", report.conditionCoverage.requiredConditionsTotal),
59
+ line("Required conditions satisfied", report.conditionCoverage.requiredConditionsSatisfied),
60
+ line("Required conditions missing", report.conditionCoverage.requiredConditionsMissing.join(", ") || "(none)"),
61
+ line("Required conditions lost", report.conditionCoverage.requiredConditionsLost.join(", ") || "(none)"),
62
+ line("Last-witness-loss count", report.conditionCoverage.lastWitnessLossCount)
63
+ ].join("\n"));
64
+ sections.push([
65
+ "=== 5. Producer/readiness agreement ===",
66
+ renderAgreement("Producer-condition agreement", report.producerConditionAgreement),
67
+ renderAgreement("requiredEvidenceLost agreement", report.requiredEvidenceLossAgreement),
68
+ renderAgreement("Producer/readiness relationship", report.producerReadinessAgreement)
69
+ ].join("\n"));
70
+ sections.push([
71
+ "=== 6. Prompt and judge agreement ===",
72
+ "Note: the orchestrator does not expose a literal upstream promptMode field. stageMayRenderNormalPrompt (a boolean derived from structured blocked-stage evidence) is the bounded substitute used here.",
73
+ renderAgreement("Readiness/prompt agreement", report.readinessPromptAgreement),
74
+ renderAgreement("Readiness/expected-judge agreement", report.readinessExpectedJudgeAgreement),
75
+ renderAgreement("Expected/actual-judge agreement", report.expectedActualJudgeAgreement)
76
+ ].join("\n"));
77
+ sections.push([
78
+ "=== 7. Correction and final-report agreement ===",
79
+ renderAgreement("Judge/correction agreement", report.judgeCorrectionAgreement),
80
+ renderAgreement("Judge/final-eligibility agreement", report.judgeFinalEligibilityAgreement),
81
+ renderAgreement("Eligibility/final-artifact agreement", report.eligibilityFinalArtifactAgreement)
82
+ ].join("\n"));
83
+ sections.push(["=== 8. Lifecycle integrity ===", renderAgreement("Lifecycle-integrity agreement", report.lifecycleIntegrityAgreement)].join("\n"));
84
+ sections.push([
85
+ "=== 9. Determinism and immutability ===",
86
+ line("Determinism availability", report.determinism.availability),
87
+ line("Repeat count", report.determinism.repeatCount),
88
+ line("Deterministic", report.determinism.deterministic),
89
+ line("Fixture self-immutable", report.immutability.fixtureSelfImmutable),
90
+ line("Fixture immutability reason", report.immutability.fixtureImmutabilityReason)
91
+ ].join("\n"));
92
+ const allContradictionCounts = [
93
+ report.producerConditionAgreement,
94
+ report.requiredEvidenceLossAgreement,
95
+ report.producerReadinessAgreement,
96
+ report.readinessPromptAgreement,
97
+ report.readinessExpectedJudgeAgreement,
98
+ report.expectedActualJudgeAgreement,
99
+ report.judgeCorrectionAgreement,
100
+ report.judgeFinalEligibilityAgreement,
101
+ report.eligibilityFinalArtifactAgreement,
102
+ report.lifecycleIntegrityAgreement
103
+ ].reduce((sum, a) => sum + a.contradictions.totalCount, 0);
104
+ sections.push([
105
+ "=== 10. Contradictions and unavailable evidence ===",
106
+ line("Total contradiction count across all components", allContradictionCounts),
107
+ line("Unavailable sections", report.limitations.unavailableSections.join(", ") || "(none)")
108
+ ].join("\n"));
109
+ sections.push(["=== 11. Limitations ===", ...(report.limitations.notes.length > 0 ? report.limitations.notes.map((n) => ` - ${n}`) : [" (none)"])].join("\n"));
110
+ return sections.join("\n\n") + "\n";
111
+ }
@@ -187,8 +187,70 @@ function renderStrategySection(strategy, index) {
187
187
  ${table(["Status", "Repeat Count"], [[strategy.assurance.status, String(strategy.assurance.repeatCount)]])}
188
188
  ${boundedListNote(strategy.assurance.issues)}
189
189
  ${table(["Code", "Run", "Field Path", "Message"], assuranceIssueRows)}
190
+ ${strategy.producerReadinessBridge ? renderProducerReadinessBridgeSection(strategy.producerReadinessBridge) : ""}
190
191
  </section>`;
191
192
  }
193
+ function renderProducerReadinessSideSection(label, side) {
194
+ if (side === null) {
195
+ return `<h4>${escapeHtml(label)}</h4><p class="muted">Not supplied.</p>`;
196
+ }
197
+ const truncationRows = side.truncationEvaluation.items.map((t) => [
198
+ t.groupId,
199
+ t.cause,
200
+ t.availability,
201
+ String(t.limit),
202
+ String(t.used),
203
+ t.reason ?? "",
204
+ ]);
205
+ function agreementSection(agreementLabel, agreement) {
206
+ if (agreement === null) {
207
+ return `<h5>${escapeHtml(agreementLabel)}</h5><p class="muted">Unavailable.</p>`;
208
+ }
209
+ const rows = agreement.contradictions.map((c) => [c.field, String(c.rawValue), String(c.supplementalValue), c.availability]);
210
+ return `<h5>${escapeHtml(agreementLabel)}</h5>
211
+ <p>Producer parity preserved: ${escapeHtml(agreement.upstreamProducerParityPreserved)}</p>
212
+ ${table(["Field", "Raw Value", "Supplemental Value", "Availability"], rows)}`;
213
+ }
214
+ return `<h4>${escapeHtml(label)}</h4>
215
+ ${renderRatioMetricTable("Expected Owner Present", side.ownerEvaluation.expectedOwnerPresent)}
216
+ ${renderRatioMetricTable("Forbidden Owner Present", side.ownerEvaluation.forbiddenOwnerPresent)}
217
+ ${renderCountMetricTable("Owner False Positives", side.ownerEvaluation.falsePositiveCount)}
218
+ ${renderCountMetricTable("Owner False Negatives", side.ownerEvaluation.falseNegativeCount)}
219
+ <h5>Truncation Classification</h5>
220
+ ${boundedListNote(side.truncationEvaluation)}
221
+ ${table(["Group", "Cause", "Availability", "Limit", "Used", "Reason"], truncationRows)}
222
+ ${agreementSection("Packet/Raw Agreement", side.packetAgreement)}
223
+ ${agreementSection("Report/Raw Agreement", side.reportAgreement)}`;
224
+ }
225
+ function renderProducerReadinessBridgeSection(bridge) {
226
+ if (bridge.status === "not-applicable") {
227
+ return `<h4>Producer-Readiness Bridge</h4><p class="muted">${escapeHtml(bridge.reason)}</p>`;
228
+ }
229
+ const criticality = bridge.criticalityEvaluation;
230
+ return `<h4>Producer-Readiness Bridge</h4>
231
+ ${renderProducerReadinessSideSection("Implementation", bridge.implementation)}
232
+ ${renderProducerReadinessSideSection("Test", bridge.testImplementation)}
233
+ <h5>Readiness Agreement</h5>
234
+ ${bridge.readinessAgreement === null
235
+ ? `<p class="muted">Not supplied.</p>`
236
+ : table(["Observed Decision", "Decision Agreement", "Issue-Code Agreement", "Invalid Ready", "Valid Blocked", "Valid Refresh-Required"], [
237
+ [
238
+ String(bridge.readinessAgreement.decisionAgreement.observedDecision),
239
+ String(bridge.readinessAgreement.decisionAgreement.decisionAgreement),
240
+ String(bridge.readinessAgreement.decisionAgreement.issueCodesAgreement),
241
+ String(bridge.readinessAgreement.invalidReady.invalidReady),
242
+ String(bridge.readinessAgreement.validBlocked.validBlocked),
243
+ String(bridge.readinessAgreement.validBlocked.validRefreshRequired),
244
+ ],
245
+ ])}
246
+ <h5>Criticality Evaluation</h5>
247
+ ${criticality === null
248
+ ? `<p class="muted">Not supplied.</p>`
249
+ : `${renderRatioMetricTable("Mapped Critical Completeness", criticality.mappedCriticalCompleteness)}
250
+ <p>Partially mapped (excluded from complete): ${escapeHtml(criticality.partiallyMappedCriticalIds.join(", ") || "none")}</p>
251
+ <p>Unmapped: ${escapeHtml(criticality.unmappedCriticalIds.join(", ") || "none")}</p>
252
+ <p>Conflicting: ${escapeHtml(criticality.conflictingCriticalityResponsibilityIds.join(", ") || "none")}</p>`}`;
253
+ }
192
254
  export function renderContextStrategyComparisonV043Html(report) {
193
255
  if (report === null) {
194
256
  return `<section><h2>V0.4.3 Stage-Context Evidence</h2><p>Not applicable to this plugin.</p></section>`;
@@ -162,6 +162,73 @@ function renderStrategy(lines, strategy, index) {
162
162
  lines.push(fieldLine("Repeat Count", strategy.assurance.repeatCount));
163
163
  lines.push("Issues:");
164
164
  pushBoundedList(lines, strategy.assurance.issues, (issue) => `${issue.code} run=${issue.runNumber ?? ""} field=${issue.fieldPath ?? ""} ${issue.message}`);
165
+ if (strategy.producerReadinessBridge) {
166
+ renderProducerReadinessBridge(lines, strategy.producerReadinessBridge);
167
+ }
168
+ }
169
+ function renderProducerReadinessSide(lines, label, side) {
170
+ pushSection(lines, `Producer-Readiness Bridge: ${label}`);
171
+ if (side === null) {
172
+ lines.push("- not supplied");
173
+ return;
174
+ }
175
+ pushRatioMetric(lines, "Expected Owner Present", side.ownerEvaluation.expectedOwnerPresent);
176
+ pushRatioMetric(lines, "Forbidden Owner Present", side.ownerEvaluation.forbiddenOwnerPresent);
177
+ pushCountMetric(lines, "Owner False Positives", side.ownerEvaluation.falsePositiveCount);
178
+ pushCountMetric(lines, "Owner False Negatives", side.ownerEvaluation.falseNegativeCount);
179
+ pushSection(lines, "Truncation Classification");
180
+ pushBoundedList(lines, side.truncationEvaluation, (t) => `group=${t.groupId} cause=${t.cause} availability=${t.availability} limit=${t.limit} used=${t.used}`);
181
+ for (const [agreementLabel, agreement] of [
182
+ ["Packet/Raw Agreement", side.packetAgreement],
183
+ ["Report/Raw Agreement", side.reportAgreement],
184
+ ]) {
185
+ pushSection(lines, agreementLabel);
186
+ if (agreement === null) {
187
+ lines.push("- unavailable");
188
+ continue;
189
+ }
190
+ lines.push(`Producer Parity Preserved: ${agreement.upstreamProducerParityPreserved === null ? "unavailable" : agreement.upstreamProducerParityPreserved}`);
191
+ lines.push("Contradictions:");
192
+ pushDashList(lines, agreement.contradictions.map((c) => `${c.field}: raw=${sanitizeScalar(c.rawValue)} supplemental=${sanitizeScalar(c.supplementalValue)}`));
193
+ }
194
+ }
195
+ function renderProducerReadinessBridge(lines, bridge) {
196
+ pushSection(lines, "Producer-Readiness Bridge");
197
+ lines.push(fieldLine("Status", bridge.status));
198
+ if (bridge.status === "not-applicable") {
199
+ lines.push(fieldLine("Reason", bridge.reason));
200
+ return;
201
+ }
202
+ renderProducerReadinessSide(lines, "Implementation", bridge.implementation);
203
+ renderProducerReadinessSide(lines, "Test", bridge.testImplementation);
204
+ pushSection(lines, "Readiness Agreement");
205
+ if (bridge.readinessAgreement === null) {
206
+ lines.push("- not supplied");
207
+ }
208
+ else {
209
+ const decision = bridge.readinessAgreement.decisionAgreement;
210
+ lines.push(fieldLine("Observed Decision", decision.observedDecision));
211
+ lines.push(fieldLine("Decision Agreement", decision.decisionAgreement));
212
+ lines.push(fieldLine("Issue-Code Agreement", decision.issueCodesAgreement));
213
+ lines.push("Observed Issue Codes:");
214
+ pushDashList(lines, decision.observedIssueCodes);
215
+ lines.push(fieldLine("Invalid Ready", bridge.readinessAgreement.invalidReady.invalidReady));
216
+ lines.push(fieldLine("Valid Blocked", bridge.readinessAgreement.validBlocked.validBlocked));
217
+ lines.push(fieldLine("Valid Refresh-Required", bridge.readinessAgreement.validBlocked.validRefreshRequired));
218
+ }
219
+ pushSection(lines, "Criticality Evaluation");
220
+ if (bridge.criticalityEvaluation === null) {
221
+ lines.push("- not supplied");
222
+ }
223
+ else {
224
+ pushRatioMetric(lines, "Mapped Critical Completeness", bridge.criticalityEvaluation.mappedCriticalCompleteness);
225
+ lines.push(`Fully Mapped: ${bridge.criticalityEvaluation.fullyMappedCriticalIds.join(", ") || "none"}`);
226
+ lines.push(`Partially Mapped: ${bridge.criticalityEvaluation.partiallyMappedCriticalIds.join(", ") || "none"}`);
227
+ lines.push(`Unmapped: ${bridge.criticalityEvaluation.unmappedCriticalIds.join(", ") || "none"}`);
228
+ lines.push(`Conflicting: ${bridge.criticalityEvaluation.conflictingCriticalityResponsibilityIds.join(", ") || "none"}`);
229
+ }
230
+ pushSection(lines, "Producer-Readiness Bridge Warnings");
231
+ pushBoundedList(lines, bridge.warnings, (w) => w);
165
232
  }
166
233
  function renderV043Section(lines, section) {
167
234
  if (section === null) {
@@ -0,0 +1,33 @@
1
+ export const REQUIRED_PACKAGE_CONTENTS = [
2
+ "CHANGELOG.md",
3
+ "LICENSE",
4
+ "README.md",
5
+ "dist/scripts/run-final-demo.js",
6
+ "dist/src/index.js",
7
+ "package.json",
8
+ ];
9
+ function normalizeTarballPath(file) {
10
+ const normalized = file.replace(/\\/g, "/");
11
+ return normalized.startsWith("package/")
12
+ ? normalized.slice("package/".length)
13
+ : normalized;
14
+ }
15
+ export function detectMissingRequiredContents(options) {
16
+ const present = new Set(options.files.map(normalizeTarballPath));
17
+ const required = [...(options.requiredFiles ?? REQUIRED_PACKAGE_CONTENTS)]
18
+ .map(normalizeTarballPath)
19
+ .sort((left, right) => left.localeCompare(right));
20
+ const missing = required.filter((file) => !present.has(file));
21
+ const findings = missing.map((file, index) => ({
22
+ id: `${options.checkId}-required-missing-${index}`,
23
+ title: `Required file missing from npm tarball: package/${file}`,
24
+ severity: "blocker",
25
+ category: "package-content",
26
+ description: `The required release file 'package/${file}' is absent from the npm package inventory`,
27
+ evidence: `Missing required path: package/${file}`,
28
+ affectedFiles: [file],
29
+ recommendation: `Include '${file}' in the package files allowlist or restore the expected build output`,
30
+ releaseImpact: "Blocker: the npm package is incomplete and must not be published",
31
+ }));
32
+ return { missing, findings };
33
+ }
@@ -3,6 +3,7 @@ import { runSecurityCommand, resolveNpmCommand } from "../commandRunner.js";
3
3
  import { writeCheckResult } from "../artifacts.js";
4
4
  import { parseNpmPackDryRun } from "./parseNpmPackDryRun.js";
5
5
  import { detectForbiddenContents } from "./forbiddenPackageContents.js";
6
+ import { detectMissingRequiredContents } from "./requiredPackageContents.js";
6
7
  // Run npm pack --dry-run and inspect the resulting file list for forbidden contents.
7
8
  // Does not publish anything.
8
9
  export async function runPackageChecks(options) {
@@ -32,7 +33,12 @@ export async function runPackageChecks(options) {
32
33
  allowedExceptions: allowedPackageExceptions,
33
34
  checkId: "npm-pack",
34
35
  });
35
- allFindings.push(...contentFindings);
36
+ const { findings: missingRequiredFindings } = detectMissingRequiredContents({
37
+ files: parsed.files,
38
+ checkId: "npm-pack",
39
+ });
40
+ const packageFindings = [...contentFindings, ...missingRequiredFindings];
41
+ allFindings.push(...packageFindings);
36
42
  const packCheck = {
37
43
  id: "npm-pack-dry-run",
38
44
  name: "npm pack --dry-run (tarball file list)",
@@ -41,18 +47,18 @@ export async function runPackageChecks(options) {
41
47
  ? "failed"
42
48
  : parsed.parseError && parsed.files.length === 0
43
49
  ? "warning"
44
- : contentFindings.length > 0
50
+ : packageFindings.length > 0
45
51
  ? "failed"
46
52
  : "passed",
47
- severity: contentFindings.length > 0
48
- ? contentFindings.some((f) => f.severity === "blocker")
53
+ severity: packageFindings.length > 0
54
+ ? packageFindings.some((f) => f.severity === "blocker")
49
55
  ? "blocker"
50
56
  : "major"
51
57
  : "informational",
52
58
  startedAt,
53
59
  finishedAt,
54
60
  durationMs: cmd.durationMs,
55
- findings: contentFindings,
61
+ findings: packageFindings,
56
62
  skippedReason: undefined,
57
63
  command: "npm pack --dry-run",
58
64
  };
package/docs/METRICS.md CHANGED
@@ -330,3 +330,114 @@ Every ratio metric below reports `availability` (`available`, `unavailable`, or
330
330
  Caveat: reports `unavailable` when no target-immutability configuration was supplied for the run; a configured, unchanged target reports an available count of zero.
331
331
 
332
332
  Repeated-run determinism (`StageContextDeterminismResultV1` in `src/evaluation/stageContextDeterminism`) reports whether repeated canonical runs (`repeatCount` 1 through 10, run 1 as baseline) produce identical canonicalized run values via SHA-256 digest comparison. A single run reports `not-applicable`; a canonicalization failure (for example a circular reference) reports `unavailable`.
333
+
334
+ ## Producer-readiness bridge metrics (v0.4.4)
335
+
336
+ Implemented in `src/evaluation/stageContextMetrics` (`calculateOwnerMetrics.ts`, `calculateAllocationMetrics.ts`, `calculateTruncationClassification.ts`, `calculateSupplementalRawAgreement.ts`, `calculateReadinessAgreement.ts`, `calculateCriticalityMetrics.ts`) and composed once per run by `evaluateProducerReadinessBridge.ts`. These metrics read only evidence Batch 1's readers and the existing `v0.4.3` `ContextCapsule`/`RetrievalAuditRecord` readers already preserve; none reimplement upstream owner selection, evidence allocation, producer parity, or orchestrator readiness. Every metric below uses the same `available`/`unavailable`/`not-applicable` availability model as the `v0.4.3` metrics above; unavailable and not-applicable remain distinct from an available zero.
337
+
338
+ - `selectedOwnerEvidence` / `expectedOwnerPresent` / `forbiddenOwnerPresent` / owner false positives / false negatives
339
+ Meaning: the owner identities the frozen my-dev-kit producer already selected (`ContextCapsule.selectedOwners`), compared against explicit fixture-declared required/allowed/forbidden owner expectations.
340
+ Caveat: with no owner expectations declared, all four ratio/count metrics report `not-applicable`, not zero. An owner outside a fixture-declared closed set (or explicitly forbidden) is a false positive only when that closed set or forbidden set actually exists.
341
+ - `requiredGroupCapacity` / `usedReservation` / `borrowedCapacity` / `unusedCapacity`
342
+ Meaning: per evidence-group allocation facts read directly from `ContextCapsule.evidenceGroups` (`limit`, `usedCount`).
343
+ Caveat: `borrowedCapacity` always reports `unavailable` — no frozen my-dev-kit artifact field exposes cross-group capacity borrowing. `unusedCapacity` is computed (`limit - usedCount`) only when a limit is declared and the result is non-negative; a negative result reports `unavailable` with a diagnostic reason rather than a negative number.
344
+ - `requiredEvidenceOmitted`
345
+ Meaning: fixture-required evidence absent from observed evidence.
346
+ Caveat: `requiredEvidenceOmittedEntries[].groupId` is always `null` under the current expectation model — expectation items do not declare a group, so group linkage cannot be derived without inventing a mapping.
347
+ - Truncation classification (`avoidable` / `genuine-hard-limit` / `unresolved` / `none`)
348
+ Meaning: classifies each `TruncationRecord` using only `limit`, `used`, and `requiredEvidenceLost`. `avoidable` when required evidence was lost while `used` remained below the declared `limit`; `genuine-hard-limit` when `used` reached or exceeded the limit; `unresolved` when no limit is declared; `none` when no required evidence was lost.
349
+ Caveat: missing required evidence alone never proves `avoidable` — it requires the authoritative `requiredEvidenceLost` and `limit`/`used` evidence together.
350
+ - Supplemental/raw agreement
351
+ Meaning: per-field comparison between a Batch 1 supplemental document and the raw `ContextCapsule`/`RetrievalAuditRecord`, limited to fields whose vocabularies are directly, losslessly comparable (canonical repository identity, role, freshness, and truncation-as-yes/no).
352
+ Caveat: adequacy agreement always reports `unavailable` — my-dev-kit's four-sentence `ContextAdequacyStatus` values have no verified mapping onto the orchestrator's five-slug `DeclaredAdequacy` vocabulary, and none is invented. Missing evidence on one side reports `unavailable`, never a forced contradiction. `upstreamProducerParityPreserved` reflects that a successfully read raw pair is itself observed evidence the frozen `assertRawEvidenceParity()` write-time guard already held — it is never recomputed by comparing fields.
353
+ - Readiness agreement (`decisionAgreement`, `invalidReady`, `validBlocked`)
354
+ Meaning: compares the observed `OrchestratorContextReadinessResultV1` against an explicit fixture-declared readiness expectation. `invalidReady` is available `true` only when the observed decision is `ready` while the fixture explicitly requires blocking behavior with expected issue codes. `validBlocked` requires the observed decision, allowed decisions, and issue codes to all agree with the fixture.
355
+ Caveat: with no readiness expectation, all three report `not-applicable`. With no readiness input, all three report `unavailable`. None of these ever call or reimplement the frozen orchestrator's `contextReadiness.ts`.
356
+ - Criticality-overlay agreement / `mappedCriticalCompleteness`
357
+ Meaning: compares fixture-declared expected criticality per responsibility ID against the `criticality`/`mappingStatus` fields my-dev-kit's own `ResponsibilityMapping` already carries. `mappedCriticalCompleteness` counts only applicable, full-mapping-required, expected-critical responsibilities with resolvable mapping status; partially mapped and unmapped responsibilities never count as complete.
358
+ Caveat: a responsibility with no matching raw mapping entry reports `unavailable`/`missingMappingEvidenceCriticalIds`, and is excluded from the denominator rather than treated as unmapped. With zero resolvable denominator entries, `mappedCriticalCompleteness` reports `not-applicable`, not an available zero.
359
+
360
+ No composite score, grade, ranking, or lab-generated readiness verdict is calculated anywhere in this section.
361
+
362
+ ## Context-integrity metrics (v0.4.5)
363
+
364
+ Implemented in `src/evaluation/stageContextMetrics` and composed once per run by the same `evaluateProducerReadinessBridge.ts` used by the `v0.4.4` metrics above. These metrics read only condition-aware producer evidence mirrored exactly from the published `my-dev-kit` `v1.10.4` contract and run-integrity evidence mirrored exactly from the published `my-dev-kit-orchestrator` `v1.2.3` contract; none reimplement upstream witness-adequacy, allocation, judge, correction, or lifecycle policy. Every metric below uses the same `available`/`unavailable`/`not-applicable` availability model as the `v0.4.3`/`v0.4.4` metrics; agreement-style metrics additionally report one of the shared `AgreementOutcomeV1` values (`agreement`, `contradiction`, `insufficient-evidence`, `unsupported-legacy-evidence`, `not-applicable`), never a lab-derived pass/fail verdict.
365
+
366
+ **Allocation and spillover** (`calculateAllocationMetrics.ts`, per-group and aggregate over `ContextCapsule.groupTruncation`):
367
+
368
+ - `requiredGroupCapacity` / `usedReservation` / `unusedCapacity`
369
+ Meaning: per-group hard limit, used count, and computed unused capacity (`limit - usedCount`) read from `EvidenceGroup`.
370
+ Caveat: `requiredGroupCapacity`/`unusedCapacity` report `unavailable` when no hard limit is declared; a negative computed remainder is treated as a data inconsistency and reported `unavailable` with a diagnostic reason rather than a negative number.
371
+ - `borrowedCapacity`
372
+ Meaning: cross-group capacity borrowing.
373
+ Caveat: always reports `unavailable` — no frozen `my-dev-kit` artifact field exposes cross-group borrowing; this is never inferred from other fields.
374
+ - Per-group allocation fields (`reservation`, `initiallySelectedCount`, `unusedReservationContributed`, `borrowedCapacity`, `governingHardBound`, `requiredOmittedCount`, `optionalOmittedCount`, `adequacyAffected`, `aggregateCapacityUsed`, `aggregateCapacityRemaining`)
375
+ Meaning: read directly, field-for-field, from each `GroupTruncationEntry`.
376
+ Caveat: a group entry with none of these additive fields set reports `unavailable` for the whole entry (legacy schema-major-1 evidence), never zero.
377
+ - Aggregate allocation totals (`totalReservation`, `totalInitiallySelected`, `totalUnusedReservationContributed`, `totalBorrowedCapacity`, `totalRequiredOmitted`, `totalOptionalOmitted`, `totalDropped`) and group lists (`groupsContributingUnusedReservation`, `groupsBorrowingCapacity`, `groupsWithRequiredOmission`, `groupsWithOptionalOnlyOmission`, `groupsWithAdequacyAffected`)
378
+ Meaning: sums and group-ID lists across all evidence groups.
379
+ Caveat: `not-applicable` when there are no evidence groups; `unavailable` when no group exposes allocation diagnostics; a total is reported `null` (`partial: true`) rather than partially summed when any contributing group lacks a needed field.
380
+ - `requiredEvidenceOmitted`
381
+ Meaning: fixture-required evidence (from `StageContextExpectationFixtureV1`) missing from observed evidence.
382
+ Caveat: `groupId` on each omitted-evidence entry is always `null` — expectation items do not declare a group, so group linkage is never invented. `not-applicable` when nothing required is missing.
383
+ - Truncation classification (`avoidable` / `genuine-hard-limit` / `unresolved` / `none`)
384
+ Meaning: classifies each `TruncationRecord` using only `limit`, `used`, and `requiredEvidenceLost` — unchanged from the `v0.4.4` classification, now composed alongside the `v0.4.5` allocation/spillover evidence.
385
+ - Spillover diagnostics (`groupsContributing`, `groupsBorrowing`, `totalContributed`, `totalBorrowed`, `contributionCoversBorrowing`)
386
+ Meaning: which groups contributed unused reservation versus borrowed capacity, and whether total contribution covers total borrowing.
387
+ Caveat: `unavailable` when no group exposes `v1.10.3`/`v1.10.4` allocation diagnostics.
388
+
389
+ **Condition coverage** (`calculateConditionCoverageMetrics.ts`, over `roleConditionCoverage`):
390
+
391
+ - `requiredConditionsTotal` / `requiredConditionsSatisfied` / `requiredConditionsMissing` / `requiredConditionsLost`
392
+ Meaning: counts of required conditions by coverage state — `satisfied` (`conditionSatisfied`), `lost-to-allocation` (`lostRequiredCondition`), or `missing-evidence` (neither).
393
+ - `optionalConditionsTotal` / `optionalConditionsSatisfied` / `optionalConditionsMissing`
394
+ Meaning: the same breakdown for non-required conditions.
395
+ - `witnessEvidence`
396
+ Meaning: per-condition witness detail (`witnessPolicy`, `requiredWitnessCount`, `availableWitnessCount`, `retainedWitnessCount`, `retainedWitnessIds`, `adequateWitnessRemains`, `coverageState`, `lossReason`, `evidenceGroupIds`) read directly from each `RoleConditionCoverage` entry.
397
+ Caveat: retained-witness identifiers are never fabricated from counts alone; only IDs the producer actually supplied are reported.
398
+ - `lastWitnessLossCount`
399
+ Meaning: count of required conditions that lost their last adequate witness (`lostRequiredCondition`).
400
+ Caveat: a real, available zero (no last-witness loss) is distinct from `unavailable` (no condition-coverage evidence at all).
401
+ - `conditionToGroupMapping`
402
+ Meaning: whether each condition's `evidenceGroupIds` reference known evidence groups (`mapped`, `unknownGroupIds`).
403
+ - Overall availability
404
+ Caveat: the entire metric block reports `unavailable` when `roleConditionCoverage` is absent — this is the expected, documented case for the `v0.4.5` failed-run fixture, which predates condition-level diagnostics (legacy schema-major-1 producer evidence), never treated as an evaluated-empty result.
405
+
406
+ **Agreement metrics** (comparing producer evidence against itself, and producer evidence against orchestrator run-integrity evidence):
407
+
408
+ - `producerConditionAgreement`
409
+ Meaning: compares `roleAdequacy.status` against condition-coverage evidence; flags `PRODUCER_INADEQUATE_BUT_ALL_REQUIRED_CONDITIONS_RETAINED` and `PRODUCER_ADEQUATE_BUT_REQUIRED_CONDITION_LOST` contradictions.
410
+ Caveat: reports `unsupported-legacy-evidence` (not `contradiction` or `agreement`) when condition-coverage evidence itself is unavailable — this is the case for the failed-run fixture.
411
+ - `requiredEvidenceLossAgreement`
412
+ Meaning: compares `truncation.requiredEvidenceLost` against explicit condition-loss/required-omission evidence; flags `REQUIRED_EVIDENCE_LOST_FALSE_BUT_CONDITION_LOSS_DETECTED` and `REQUIRED_EVIDENCE_LOST_TRUE_BUT_NO_CONDITION_OR_GROUP_LOSS_DETECTED`.
413
+ - `capsuleAuditConditionAgreement`
414
+ Meaning: whether the context capsule and retrieval audit record agree on `roleConditionCoverage`, `truncation`, and `roleAdequacy`, using the existing capsule/audit consistency selector.
415
+ - `readinessPromptAgreement`
416
+ Meaning: compares `gate.readinessClassification` against `stageMayRenderNormalPrompt` (derived from structured blocked-stage evidence — **not** a literal upstream `promptMode` field, which the orchestrator does not expose) for context-sensitive stages (`implementation`, `test-implementation`); flags `READY_BUT_PROMPT_NOT_NORMAL` and `REFRESH_REQUIRED_BUT_PROMPT_NORMAL`.
417
+ Caveat: `not-applicable` for non-context-sensitive stages.
418
+ - `readinessExpectedJudgeAgreement`
419
+ Meaning: checks the gate's own `contextReady`/`expectedJudgeVerdict` invariant; flags `CONTEXT_READY_BUT_EXPECTED_NOT_PASS` and `CONTEXT_NOT_READY_BUT_EXPECTED_NOT_NEED_CONTEXT`.
420
+ - `expectedActualJudgeAgreement`
421
+ Meaning: compares the gate's `expectedJudgeVerdict` against the parsed `authoredJudgeVerdict`; flags malformed/missing judge verdicts and the upstream `JUDGE_VERDICT_CONTRADICTS_RUN_INTEGRITY` code (preserved verbatim when the orchestrator's own `blockingCodes` include it) when an authored `PASS` contradicts a canonical `NEED_CONTEXT` requirement.
422
+ Caveat: `insufficient-evidence` when no `judgeIntegrity` evidence was supplied. A syntactically valid, accepted verdict that legitimately differs from the expected one (e.g. a correction-route or terminal blocked verdict) is not itself flagged as a contradiction.
423
+ - `judgeCorrectionAgreement`
424
+ Meaning: checks that a `PASS` verdict has no active correction route, that a corrective verdict requiring correction has one, and that `acceptedCorrectionStage` matches the structured route's `routedStage`; flags `PASS_WITH_ACTIVE_CORRECTION_ROUTE`, `CORRECTIVE_VERDICT_WITHOUT_ROUTE`, and `CORRECTION_DESTINATION_MISMATCH`.
425
+ - `judgeFinalEligibilityAgreement`
426
+ Meaning: checks that `finalReportEligible` only holds when the authored verdict is `PASS`, parsed, accepted, and matches the expected verdict; flags `ELIGIBLE_WITH_NON_PASS_JUDGE`, `ELIGIBLE_WITH_MALFORMED_OR_MISSING_JUDGE`, `ELIGIBLE_WITH_UNACCEPTED_JUDGE`, and `ELIGIBLE_WITH_UNMATCHED_EXPECTED_VERDICT`.
427
+ - `eligibilityFinalArtifactAgreement`
428
+ Meaning: checks eligibility against final-artifact presence and verdict; flags `ELIGIBLE_BUT_ARTIFACT_MISSING`, `INELIGIBLE_BUT_ARTIFACT_PRESENT`, `NEED_CONTEXT_FOLLOWED_BY_FINAL_PASS` (or the more general `INELIGIBLE_WITH_FINAL_PASS`), and `FINAL_ARTIFACT_MALFORMED_VERDICT`. This is the metric that surfaces the real historical `v1.11.0` Batch 1 failed-run's contradiction: a `NEED_CONTEXT` gate followed by a final report with verdict `PASS`.
429
+ - `lifecycleIntegrityAgreement`
430
+ Meaning: per-stage lifecycle entries (`completionBasis`: `not-complete` / `artifact-presence-only` / `manual-record`) checked against expected run-integrity blocking; flags `MANUAL_MARK_COMPLETE_BYPASS_SUCCEEDED` when a stage that should be blocked (by `gate.blockedStageNames` or final-report ineligibility) resolved to `complete` anyway, whether through a manual mark-complete record or artifact presence alone.
431
+ Caveat: `not-applicable` when no lifecycle evidence was supplied.
432
+ - `endToEndSummary` (`category`: `full-agreement` / `contradiction-present` / `insufficient-evidence` / `unsupported-legacy-evidence`)
433
+ Meaning: aggregates all component agreement outcomes above (plus `producerReadiness` from the `v0.4.4` bridge) — any contradiction anywhere makes the category `contradiction-present`; otherwise any `insufficient-evidence` or `unsupported-legacy-evidence` component determines the category; only when every component agrees is the category `full-agreement`.
434
+ Caveat: this is an aggregation of agreement/contradiction state, not a composite score, grade, ranking, or release verdict — no such value is calculated anywhere in this section.
435
+
436
+ **Fixture assurance:**
437
+
438
+ - Fixture hash verification (`src/evaluation/ecosystemFixtures/verifyFixtureHashes.ts`)
439
+ Meaning: SHA-256 comparison of tracked fixture files against the manifest's recorded hashes.
440
+ Interpretation: `ok: false` means the on-disk fixture bytes no longer match what was frozen; evaluation results built from a failed hash check should not be trusted.
441
+ - Determinism and fixture self-immutability
442
+ Meaning: reuses `calculateStageContextDeterminism`/`canonicalizeStageContextRun` (`v0.4.3`) to confirm repeated evaluations of the same fixture produce identical canonicalized results, and re-runs fixture hash verification to confirm the frozen bytes were not mutated by evaluation.
443
+ Caveat: this is fixture-level self-immutability, not the `v0.4.3` live-target-mutation check — no live target repository is exercised by this evaluation path.
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@dailephd/my-dev-kit-lab",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "type": "module",
5
5
  "description": "Evidence, benchmark, and evaluation companion for my-dev-kit.",
6
6
  "bin": {
7
7
  "my-dev-kit-lab": "dist/scripts/run-final-demo.js"
8
8
  },
9
9
  "files": [
10
+ "CHANGELOG.md",
10
11
  "dist/scripts/",
11
12
  "!dist/scripts/docs/",
12
13
  "dist/src/",
@@ -72,7 +73,7 @@
72
73
  "test:visualization-demos": "vitest run tests/visualizationDemos tests/commands/runVisualizationDemosCommand.spec.ts",
73
74
  "verify:benchmarks": "tsx scripts/verify-benchmarks.ts",
74
75
  "docs:check": "node scripts/check-docs.mjs",
75
- "verify": "npm run build && npm run test && npm run test:benchmarks && npm run test:report && npm run test:screenshot && npm run test:evaluation && npm run test:agents && npm run test:experiments && npm run test:plots && npm run test:visualization-demos && npm run test:gallery && npm run test:demo && npm run test:integration && npm run test:e2e && npm run verify:benchmarks",
76
+ "verify": "npm run build && npm run verify:benchmarks",
76
77
  "security:deps": "tsx scripts/security/runDependencyChecks.ts",
77
78
  "security:package": "tsx scripts/security/runPackageChecks.ts",
78
79
  "security:codeql": "tsx scripts/security/runCodeql.ts",
@@ -80,7 +81,8 @@
80
81
  "test:security": "vitest run tests/security/",
81
82
  "test:fuzz:smoke": "tsx scripts/security/runFuzzSmoke.ts",
82
83
  "security:validate": "tsx scripts/security/validate.ts",
83
- "audit": "tsx scripts/audits/runAudit.ts"
84
+ "audit": "tsx scripts/audits/runAudit.ts",
85
+ "report:context-integrity-smoke": "tsx scripts/report-context-integrity-smoke.ts"
84
86
  },
85
87
  "devDependencies": {
86
88
  "@types/node": "^24.0.0",
@@ -0,0 +1,99 @@
1
+ {
2
+ "_derivationNote": "LAB-DERIVED, not a byte-exact capture. Built for the same run identity/target/index/request shape as ../../failed-run using the exact local my-dev-kit v1.10.4 (commit d09068f) condition-aware contract and the exact local my-dev-kit-orchestrator v1.2.3 (commit 2cb82f0) RunIntegrityGate/JudgeIntegrity/FinalReportEligibility contract, following the same hand-distillation convention the orchestrator's own tests/fixtures/v123-batch4/corrected-run fixture uses (see manifests/corrected-replay-manifest.json for full provenance).",
3
+ "schemaVersion": "1.0.0",
4
+ "runFolder": "Z:/Users/newuser/Projects/my-dev-kit-v1/.my-dev-kit-orchestrator/runs/20260730T113740-implement-my-dev-kit-v1-11-0-b",
5
+ "gate": {
6
+ "schemaVersion": "1.0.0",
7
+ "mode": "feature",
8
+ "contextRequired": true,
9
+ "applicableContextKinds": ["implementation", "test"],
10
+ "implementationContext": {
11
+ "schemaVersion": "1.0.0",
12
+ "kind": "implementation",
13
+ "role": "implementation",
14
+ "decision": "ready",
15
+ "classification": "ready",
16
+ "stageId": "stage.feature.implementation",
17
+ "packetPath": "artifacts/implementation-context-packet.txt",
18
+ "reportPath": "reports/implementation-context-retrieval-report.txt",
19
+ "issues": [],
20
+ "warnings": [],
21
+ "blockingIssueCodes": [],
22
+ "affectedResponsibilityIds": [],
23
+ "evaluatedFreshness": "fresh",
24
+ "evaluatedAdequacy": "sufficient-with-assumptions",
25
+ "requiredEvidenceTruncated": "no",
26
+ "readyWithAssumptions": true,
27
+ "provenanceSummary": "resolved from the corrected v1.10.4 condition-aware producer contract",
28
+ "indexIdentity": "Z:/Users/newuser/Projects/my-dev-kit-v1/.my-dev-kit-context/v1.11.0-batch-1-compose-artifact-foundation/implementation"
29
+ },
30
+ "contextReady": true,
31
+ "readinessClassification": "ready",
32
+ "blockedStageNames": [],
33
+ "blockingCodes": [],
34
+ "recommendedCorrectionStage": null,
35
+ "expectedJudgeVerdict": "PASS",
36
+ "warnings": []
37
+ },
38
+ "judgeIntegrity": {
39
+ "schemaVersion": "1.0.0",
40
+ "judgeArtifactPresent": true,
41
+ "judgeVerdictParseStatus": "parsed",
42
+ "authoredJudgeVerdict": "PASS",
43
+ "expectedJudgeVerdict": "PASS",
44
+ "judgeVerdictMatchesExpected": true,
45
+ "judgeVerdictAccepted": true,
46
+ "correctionRequired": false,
47
+ "correctionBlocked": false,
48
+ "acceptedCorrectionStage": null,
49
+ "finalReportEligible": true,
50
+ "blockingCodes": [],
51
+ "acceptedCorrectionRoute": null
52
+ },
53
+ "finalReportEligibility": {
54
+ "eligible": true,
55
+ "contextReady": true,
56
+ "priorArtifactsValid": true,
57
+ "judgeIntegrity": {
58
+ "schemaVersion": "1.0.0",
59
+ "judgeArtifactPresent": true,
60
+ "judgeVerdictParseStatus": "parsed",
61
+ "authoredJudgeVerdict": "PASS",
62
+ "expectedJudgeVerdict": "PASS",
63
+ "judgeVerdictMatchesExpected": true,
64
+ "judgeVerdictAccepted": true,
65
+ "correctionRequired": false,
66
+ "correctionBlocked": false,
67
+ "acceptedCorrectionStage": null,
68
+ "finalReportEligible": true,
69
+ "blockingCodes": [],
70
+ "acceptedCorrectionRoute": null
71
+ },
72
+ "blockingCodes": []
73
+ },
74
+ "finalArtifactPresent": true,
75
+ "finalArtifactVerdict": "PASS",
76
+ "lifecycle": [
77
+ {
78
+ "artifactFile": "artifacts/implementation-report.txt",
79
+ "stageName": "implementation",
80
+ "fileExists": true,
81
+ "manualRecord": null,
82
+ "resolvedState": "complete"
83
+ },
84
+ {
85
+ "artifactFile": "artifacts/test-implementation-report.txt",
86
+ "stageName": "test-implementation",
87
+ "fileExists": true,
88
+ "manualRecord": null,
89
+ "resolvedState": "complete"
90
+ },
91
+ {
92
+ "artifactFile": "artifacts/final-report.txt",
93
+ "stageName": "final-report",
94
+ "fileExists": true,
95
+ "manualRecord": null,
96
+ "resolvedState": "complete"
97
+ }
98
+ ]
99
+ }