@dailephd/my-dev-kit-lab 0.4.4 → 0.4.6

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 (225) hide show
  1. package/CHANGELOG.md +484 -0
  2. package/README.md +39 -3
  3. package/dist/scripts/cli.js +9 -0
  4. package/dist/src/audits/core/typescriptJavaScriptAnalyzer.js +30 -12
  5. package/dist/src/cli/help.js +300 -0
  6. package/dist/src/cli/index.js +2 -0
  7. package/dist/src/cli/runLabCli.js +229 -0
  8. package/dist/src/commands/runAuditCommand.js +132 -0
  9. package/dist/src/commands/runControlledExperimentCommand.js +7 -3
  10. package/dist/{scripts/experiments/describeExperiment.js → src/commands/runExperimentDescribeCommand.js} +14 -10
  11. package/dist/{scripts/experiments/listExperiments.js → src/commands/runExperimentListCommand.js} +3 -6
  12. package/dist/{scripts/experiments/runExperiment.js → src/commands/runExperimentRunCommand.js} +80 -22
  13. package/dist/src/commands/runFinalDemoCommand.js +2 -3
  14. package/dist/src/commands/runSecurityValidationCommand.js +271 -0
  15. package/dist/src/evaluation/ecosystemFixtures/index.js +3 -0
  16. package/dist/src/evaluation/ecosystemFixtures/loadContextIntegrityFixture.js +102 -0
  17. package/dist/src/evaluation/ecosystemFixtures/manifestTypes.js +1 -0
  18. package/dist/src/evaluation/ecosystemFixtures/validateManifest.js +82 -0
  19. package/dist/src/evaluation/ecosystemFixtures/verifyFixtureHashes.js +45 -0
  20. package/dist/src/evaluation/stageContextMetrics/calculateAllocationMetrics.js +169 -0
  21. package/dist/src/evaluation/stageContextMetrics/calculateConditionCoverageMetrics.js +74 -0
  22. package/dist/src/evaluation/stageContextMetrics/calculateProducerConditionAgreement.js +113 -0
  23. package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +60 -0
  24. package/dist/src/evaluation/stageContextMetrics/calculateRunIntegrityAgreement.js +309 -0
  25. package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +12 -2
  26. package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +100 -0
  27. package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +76 -5
  28. package/dist/src/evaluation/stageContextMetrics/index.js +4 -0
  29. package/dist/src/evaluation/stageContextMetrics/runIntegrityAgreementTypes.js +1 -0
  30. package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +7 -0
  31. package/dist/src/evaluation/stageContextSelectors/index.js +1 -0
  32. package/dist/src/evaluation/stageContextSelectors/orchestratorRunIntegritySelectors.js +64 -0
  33. package/dist/src/evaluation/upstreamArtifacts/index.js +2 -0
  34. package/dist/src/evaluation/upstreamArtifacts/orchestratorRunIntegrityV1.js +33 -0
  35. package/dist/src/evaluation/upstreamArtifacts/readOrchestratorRunIntegrityV1.js +9 -0
  36. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +59 -2
  37. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +6 -1
  38. package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorRunIntegrityV1.js +177 -0
  39. package/dist/src/report/experiments/buildContextIntegrityReport.js +204 -0
  40. package/dist/src/report/experiments/contextIntegrityReportModel.js +1 -0
  41. package/dist/src/report/experiments/index.js +5 -0
  42. package/dist/src/report/experiments/renderContextIntegrityHtml.js +98 -0
  43. package/dist/src/report/experiments/renderContextIntegrityJsonReport.js +3 -0
  44. package/dist/src/report/experiments/renderContextIntegrityText.js +111 -0
  45. package/dist/src/runtime/index.js +3 -0
  46. package/dist/src/runtime/labExecutionContext.js +22 -0
  47. package/dist/src/runtime/packageResource.js +22 -0
  48. package/dist/src/runtime/packageRoot.js +37 -0
  49. package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +46 -0
  50. package/dist/src/securityValidation/packageChecks/runPackageChecks.js +11 -5
  51. package/docs/METRICS.md +83 -0
  52. package/package.json +10 -8
  53. package/dist/scripts/audits/runAudit.js +0 -135
  54. package/dist/scripts/build-gallery.js +0 -3
  55. package/dist/scripts/capture-demo-report.js +0 -3
  56. package/dist/scripts/evaluate-token-savings.js +0 -2
  57. package/dist/scripts/generate-experiment-plots.js +0 -3
  58. package/dist/scripts/generate-prompt-variants.js +0 -2
  59. package/dist/scripts/render-experiment-report.js +0 -2
  60. package/dist/scripts/run-agent-prompt.js +0 -2
  61. package/dist/scripts/run-controlled-experiment.js +0 -2
  62. package/dist/scripts/run-lab-demo.js +0 -5
  63. package/dist/scripts/run-visualization-demos.js +0 -3
  64. package/dist/scripts/security/resolveToolRoot.js +0 -16
  65. package/dist/scripts/security/runCodeql.js +0 -58
  66. package/dist/scripts/security/runDependencyChecks.js +0 -58
  67. package/dist/scripts/security/runFuzzSmoke.js +0 -29
  68. package/dist/scripts/security/runPackageChecks.js +0 -57
  69. package/dist/scripts/security/runSemgrep.js +0 -64
  70. package/dist/scripts/security/validate.js +0 -266
  71. package/dist/scripts/verify-benchmarks.js +0 -202
  72. package/examples/demo-report-input.json +0 -78
  73. package/examples/lab-demo-cases.json +0 -35
  74. package/examples/real-agent-campaign-cases.json +0 -118
  75. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/debug/res/xml/ambiguous_backup_rules.xml +0 -4
  76. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/ambiguous_backup_rules.xml +0 -4
  77. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/backup_rules.xml +0 -5
  78. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/broad_backup_rules.xml +0 -4
  79. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/data_extraction_rules.xml +0 -10
  80. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/unsupported_domain_rules.xml +0 -4
  81. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/malformed_backup_rules.xml +0 -4
  82. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/unsupported_root.xml +0 -4
  83. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/debug/res/xml/ambiguous_config.xml +0 -4
  84. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/ambiguous_config.xml +0 -4
  85. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/base_cleartext_false.xml +0 -8
  86. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/broad_and_duplicate_domains.xml +0 -8
  87. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/empty_domain.xml +0 -6
  88. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/malformed_pin.xml +0 -11
  89. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/network_security_config.xml +0 -26
  90. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -6
  91. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/unsupported_root.xml +0 -4
  92. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-dynamic.gradle +0 -7
  93. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-false.gradle +0 -9
  94. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-true.gradle +0 -13
  95. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-false.gradle.kts +0 -7
  96. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-true.gradle.kts +0 -10
  97. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/missing-release-build-type.gradle.kts +0 -7
  98. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/debug/res/xml/network_security_config.xml +0 -8
  99. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/backup_rules.xml +0 -4
  100. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/network_security_config.xml +0 -8
  101. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -7
  102. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.java +0 -8
  103. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.kt +0 -9
  104. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle +0 -11
  105. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle.kts +0 -11
  106. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/google-services.json +0 -16
  107. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/local.properties +0 -3
  108. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/binary.properties +0 -0
  109. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/oversized.json +0 -1
  110. package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/app/fake-release-keystore.jks +0 -1
  111. package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/build/generated-fake.keystore +0 -1
  112. package/tests/fixtures/android/compose-app/app/build.gradle.kts +0 -21
  113. package/tests/fixtures/android/compose-app/app/src/main/AndroidManifest.xml +0 -22
  114. package/tests/fixtures/android/compose-app/app/src/main/java/com/example/composeapp/MainActivity.kt +0 -11
  115. package/tests/fixtures/android/compose-app/build.gradle.kts +0 -4
  116. package/tests/fixtures/android/compose-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  117. package/tests/fixtures/android/compose-app/settings.gradle.kts +0 -2
  118. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/build.gradle.kts +0 -3
  119. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/gradle/libs.versions.toml +0 -5
  120. package/tests/fixtures/android/gradle-metadata-fixtures/comment-safety.gradle.kts +0 -21
  121. package/tests/fixtures/android/gradle-metadata-fixtures/dynamic-values.gradle.kts +0 -17
  122. package/tests/fixtures/android/gradle-metadata-fixtures/groovy-literal.gradle +0 -23
  123. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-malformed.properties +0 -4
  124. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-missing-url.properties +0 -3
  125. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-with-checksum.properties +0 -5
  126. package/tests/fixtures/android/java-app/app/build.gradle +0 -16
  127. package/tests/fixtures/android/java-app/app/src/main/AndroidManifest.xml +0 -19
  128. package/tests/fixtures/android/java-app/app/src/main/java/com/example/javaapp/MainActivity.java +0 -4
  129. package/tests/fixtures/android/java-app/build.gradle +0 -3
  130. package/tests/fixtures/android/java-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  131. package/tests/fixtures/android/java-app/settings.gradle +0 -2
  132. package/tests/fixtures/android/library/build.gradle.kts +0 -3
  133. package/tests/fixtures/android/library/gradle/wrapper/gradle-wrapper.properties +0 -4
  134. package/tests/fixtures/android/library/mylibrary/build.gradle.kts +0 -13
  135. package/tests/fixtures/android/library/mylibrary/src/main/AndroidManifest.xml +0 -2
  136. package/tests/fixtures/android/library/settings.gradle.kts +0 -2
  137. package/tests/fixtures/android/manifest-audit-fixtures/incomplete-intent-filter.xml +0 -14
  138. package/tests/fixtures/android/manifest-audit-fixtures/malformed-exported.xml +0 -10
  139. package/tests/fixtures/android/manifest-audit-fixtures/malformed.xml +0 -5
  140. package/tests/fixtures/android/manifest-audit-fixtures/missing-application.xml +0 -7
  141. package/tests/fixtures/android/manifest-audit-fixtures/missing-component-name.xml +0 -11
  142. package/tests/fixtures/android/manifest-audit-fixtures/permission-coverage.xml +0 -29
  143. package/tests/fixtures/android/manifest-audit-fixtures/risky-components.xml +0 -62
  144. package/tests/fixtures/android/manifest-audit-fixtures/risky-deep-links.xml +0 -45
  145. package/tests/fixtures/android/manifest-audit-fixtures/unresolved-placeholder.xml +0 -14
  146. package/tests/fixtures/android/manifest-audit-fixtures/unusual-namespace-prefix.xml +0 -11
  147. package/tests/fixtures/android/multi-module/app/build.gradle.kts +0 -22
  148. package/tests/fixtures/android/multi-module/app/src/androidTest/java/com/example/multimodule/app/ExampleInstrumentedTest.kt +0 -3
  149. package/tests/fixtures/android/multi-module/app/src/main/AndroidManifest.xml +0 -11
  150. package/tests/fixtures/android/multi-module/app/src/test/java/com/example/multimodule/app/ExampleUnitTest.kt +0 -3
  151. package/tests/fixtures/android/multi-module/build.gradle.kts +0 -5
  152. package/tests/fixtures/android/multi-module/core/build.gradle.kts +0 -14
  153. package/tests/fixtures/android/multi-module/core/src/main/AndroidManifest.xml +0 -2
  154. package/tests/fixtures/android/multi-module/feature-login/build.gradle.kts +0 -18
  155. package/tests/fixtures/android/multi-module/feature-login/src/main/AndroidManifest.xml +0 -2
  156. package/tests/fixtures/android/multi-module/gradle/libs.versions.toml +0 -8
  157. package/tests/fixtures/android/multi-module/gradle/wrapper/gradle-wrapper.properties +0 -4
  158. package/tests/fixtures/android/multi-module/settings.gradle.kts +0 -4
  159. package/tests/fixtures/android/non-android-gradle/build.gradle.kts +0 -3
  160. package/tests/fixtures/android/non-android-gradle/core/build.gradle.kts +0 -3
  161. package/tests/fixtures/android/non-android-gradle/core/src/main/java/com/example/core/Core.java +0 -4
  162. package/tests/fixtures/android/non-android-gradle/gradle/wrapper/gradle-wrapper.properties +0 -4
  163. package/tests/fixtures/android/non-android-gradle/settings.gradle.kts +0 -2
  164. package/tests/fixtures/android/partial/app/build.gradle.kts +0 -7
  165. package/tests/fixtures/android/partial/settings.gradle.kts +0 -2
  166. package/tests/fixtures/android/xml-view-app/app/build.gradle.kts +0 -17
  167. package/tests/fixtures/android/xml-view-app/app/src/main/AndroidManifest.xml +0 -31
  168. package/tests/fixtures/android/xml-view-app/app/src/main/kotlin/com/example/xmlviewapp/MainActivity.kt +0 -7
  169. package/tests/fixtures/android/xml-view-app/app/src/main/res/layout/activity_main.xml +0 -4
  170. package/tests/fixtures/android/xml-view-app/build.gradle.kts +0 -4
  171. package/tests/fixtures/android/xml-view-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  172. package/tests/fixtures/android/xml-view-app/settings.gradle.kts +0 -2
  173. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/README.md +0 -16
  174. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/build.gradle.kts +0 -4
  175. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/java/com/example/Widget.java +0 -7
  176. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/kotlin/com/example/Gadget.kt +0 -7
  177. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/README.md +0 -10
  178. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/build/Main.class +0 -1
  179. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/dist/index.js +0 -1
  180. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/generated/schema.ts +0 -1
  181. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/src/index.ts +0 -3
  182. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/vendor/lib.py +0 -2
  183. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/README.md +0 -10
  184. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/build.gradle.kts +0 -8
  185. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/settings.gradle.kts +0 -1
  186. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/java/com/example/FooService.java +0 -7
  187. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/kotlin/com/example/BarService.kt +0 -7
  188. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/java/com/example/FooServiceTest.java +0 -8
  189. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/kotlin/com/example/BarServiceTest.kt +0 -8
  190. package/tests/fixtures/audits/mixed-language/mixed-python-ts/README.md +0 -8
  191. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/app.py +0 -7
  192. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/index.ts +0 -3
  193. package/tests/fixtures/audits/mixed-language/mixed-python-ts/tests/test_app.py +0 -5
  194. package/tests/fixtures/audits/mixed-language/mixed-ts-js/README.md +0 -7
  195. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/helper.js +0 -5
  196. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/index.ts +0 -3
  197. package/tests/fixtures/audits/mixed-language/mixed-ts-js/tests/index.sample.ts +0 -5
  198. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/README.md +0 -10
  199. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/build.gradle.kts +0 -4
  200. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/pytests/test_app.py +0 -5
  201. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/app.py +0 -2
  202. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/helper.js +0 -5
  203. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/index.ts +0 -3
  204. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/java/com/example/Multiplier.java +0 -7
  205. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/kotlin/com/example/Divider.kt +0 -7
  206. package/tests/fixtures/fake-adversarial-cli.js +0 -152
  207. package/tests/fixtures/fake-my-dev-kit-cli.js +0 -83
  208. package/tests/fixtures/full-workflow-library/complete-v1.0.0.json +0 -24
  209. package/tests/fixtures/full-workflow-library/future-minor-v1.1.0-additive.json +0 -25
  210. package/tests/fixtures/stage-context-expectations/complete-v1.0.0.json +0 -230
  211. package/tests/fixtures/stage-context-expectations/future-minor-v1.1.0-additive.json +0 -232
  212. package/tests/fixtures/stage-context-expectations/invalid/malformed-json.txt +0 -1
  213. package/tests/fixtures/stage-context-expectations/invalid/non-object-root.json +0 -1
  214. package/tests/fixtures/stage-context-expectations/minimal-v1.0.0.json +0 -18
  215. package/tests/fixtures/upstream-artifacts/invalid/malformed-json.txt +0 -1
  216. package/tests/fixtures/upstream-artifacts/invalid/non-object-root.json +0 -1
  217. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/complete-v1.0.0.json +0 -504
  218. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/future-minor-v1.1.0-additive.json +0 -955
  219. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/complete-v1.0.0.json +0 -190
  220. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/future-minor-v1.1.0-additive.json +0 -327
  221. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +0 -13
  222. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +0 -7874
  223. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +0 -1076
  224. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/complete-v1.0.0.json +0 -160
  225. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/future-minor-v1.1.0-additive.json +0 -186
@@ -0,0 +1,64 @@
1
+ export function selectReadinessClassification(evidence) {
2
+ return evidence.gate.readinessClassification;
3
+ }
4
+ export function selectContextReady(evidence) {
5
+ return evidence.gate.contextReady;
6
+ }
7
+ export function selectBlockingCodes(evidence) {
8
+ return evidence.gate.blockingCodes;
9
+ }
10
+ export function selectRecommendedCorrectionStage(evidence) {
11
+ return evidence.gate.recommendedCorrectionStage;
12
+ }
13
+ export function selectExpectedJudgeVerdict(evidence) {
14
+ return evidence.gate.expectedJudgeVerdict;
15
+ }
16
+ // Prompt mode is not a field the exact v1.2.3 gate contract exposes as a literal string --
17
+ // it is a derived per-stage decision (evaluateStageRunIntegrity()). The lab represents it
18
+ // via the same contextReady/blockedStageNames facts the gate already exposes rather than
19
+ // inventing a separate "promptMode" string the upstream contract does not itself declare.
20
+ export function selectStageMayRenderNormalPrompt(evidence, stageName) {
21
+ const contextSensitive = evidence.gate.blockedStageNames.length > 0 || stageName === "implementation" || stageName === "test-implementation";
22
+ if (!contextSensitive)
23
+ return undefined;
24
+ return !evidence.gate.blockedStageNames.includes(stageName);
25
+ }
26
+ export function selectJudgeArtifactPresent(evidence) {
27
+ return evidence.judgeIntegrity?.judgeArtifactPresent;
28
+ }
29
+ export function selectJudgeVerdictParseStatus(evidence) {
30
+ return evidence.judgeIntegrity?.judgeVerdictParseStatus;
31
+ }
32
+ export function selectAuthoredJudgeVerdict(evidence) {
33
+ return evidence.judgeIntegrity?.authoredJudgeVerdict;
34
+ }
35
+ export function selectJudgeVerdictMatchesExpected(evidence) {
36
+ return evidence.judgeIntegrity?.judgeVerdictMatchesExpected;
37
+ }
38
+ export function selectJudgeVerdictAccepted(evidence) {
39
+ return evidence.judgeIntegrity?.judgeVerdictAccepted;
40
+ }
41
+ export function selectAcceptedCorrectionStage(evidence) {
42
+ return evidence.judgeIntegrity?.acceptedCorrectionStage;
43
+ }
44
+ export function selectAcceptedCorrectionRoute(evidence) {
45
+ return evidence.judgeIntegrity?.acceptedCorrectionRoute;
46
+ }
47
+ export function selectJudgeFinalReportEligible(evidence) {
48
+ return evidence.judgeIntegrity?.finalReportEligible;
49
+ }
50
+ export function selectFinalReportEligible(evidence) {
51
+ return evidence.finalReportEligibility?.eligible;
52
+ }
53
+ export function selectFinalArtifactPresent(evidence) {
54
+ return evidence.finalArtifactPresent;
55
+ }
56
+ export function selectFinalArtifactVerdict(evidence) {
57
+ return evidence.finalArtifactVerdict;
58
+ }
59
+ export function selectLifecycleEntries(evidence) {
60
+ return evidence.lifecycle;
61
+ }
62
+ export function selectLifecycleEntryForStage(evidence, stageName) {
63
+ return evidence.lifecycle.find((entry) => entry.stageName === stageName);
64
+ }
@@ -7,3 +7,5 @@ export { readImplementationContextRetrievalReportV1 } from "./readImplementation
7
7
  export { readTestContextPacketV1 } from "./readTestContextPacketV1.js";
8
8
  export { readTestContextRetrievalReportV1 } from "./readTestContextRetrievalReportV1.js";
9
9
  export { READINESS_DECISIONS, READINESS_CLASSIFICATIONS, validateOrchestratorContextReadinessResultV1, checkSupplementalReadinessIdentityConsistency } from "./orchestratorContextReadinessResultV1.js";
10
+ export { readOrchestratorRunIntegrityEvidenceV1 } from "./readOrchestratorRunIntegrityV1.js";
11
+ export { validateOrchestratorRunIntegrityEvidenceV1 } from "./validateOrchestratorRunIntegrityV1.js";
@@ -0,0 +1,33 @@
1
+ // --- src/judgeParser.ts ---------------------------------------------------------------
2
+ export const JUDGE_VERDICTS = [
3
+ "PASS",
4
+ "DESIGN_INCOMPLETE",
5
+ "PSEUDOCODE_INCOMPLETE",
6
+ "IMPLEMENTATION_MISMATCH",
7
+ "TEST_COVERAGE_INCOMPLETE",
8
+ "ARCHITECTURE_MISMATCH",
9
+ "NEED_VERIFICATION",
10
+ "NEED_CONTEXT",
11
+ "SCOPE_VIOLATION",
12
+ "BLOCKED"
13
+ ];
14
+ // --- src/correctionRouter.ts ----------------------------------------------------------
15
+ export const CORRECTABLE_STAGES = [
16
+ "architecture-context",
17
+ "behavior-model",
18
+ "pseudocode-packet",
19
+ "test-strategy",
20
+ "test-implementation",
21
+ "implementation",
22
+ "verification",
23
+ "target-architecture"
24
+ ];
25
+ export const ROUTE_STATUSES = ["pass", "correction_required", "blocked", "unknown_verdict", "missing_verdict"];
26
+ // --- src/runIntegrityGate.ts ----------------------------------------------------------
27
+ export const RUN_INTEGRITY_READINESS_CLASSIFICATIONS = ["not-required", "ready", "refresh-required"];
28
+ export const CONTEXT_SENSITIVE_STAGE_NAMES = ["implementation", "test-implementation"];
29
+ // --- src/judgeIntegrity.ts --------------------------------------------------------------
30
+ export const JUDGE_VERDICT_PARSE_STATUSES = ["parsed", "missing-artifact", "missing-verdict", "unknown-verdict"];
31
+ // --- src/artifactLifecycle.ts -----------------------------------------------------------
32
+ export const ARTIFACT_LIFECYCLE_STATES = ["missing", "incomplete", "blocked", "complete", "stale"];
33
+ export const MANUAL_ARTIFACT_LIFECYCLE_STATES = ["incomplete", "blocked", "complete"];
@@ -0,0 +1,9 @@
1
+ import { readJsonArtifactFile } from "./readJsonArtifact.js";
2
+ import { validateOrchestratorRunIntegrityEvidenceV1 } from "./validateOrchestratorRunIntegrityV1.js";
3
+ const ARTIFACT_KIND = "orchestrator-run-integrity-evidence-v1";
4
+ export async function readOrchestratorRunIntegrityEvidenceV1(sourcePath) {
5
+ const loaded = await readJsonArtifactFile(ARTIFACT_KIND, sourcePath);
6
+ if (!loaded.ok)
7
+ return loaded;
8
+ return validateOrchestratorRunIntegrityEvidenceV1(loaded.value, loaded.sourcePath);
9
+ }
@@ -909,7 +909,7 @@ function validateTestInfrastructureSummary(ctx, value, fieldPath) {
909
909
  }
910
910
  function validateGroupTruncationEntry(ctx, value, fieldPath) {
911
911
  const obj = requiredObject(ctx, value, fieldPath);
912
- return {
912
+ const result = {
913
913
  groupId: requiredString(ctx, requiredField(ctx, obj, "groupId", joinFieldPath(fieldPath, "groupId")), joinFieldPath(fieldPath, "groupId")),
914
914
  limit: requiredNullableNumber(ctx, requiredField(ctx, obj, "limit", joinFieldPath(fieldPath, "limit")), joinFieldPath(fieldPath, "limit")),
915
915
  availableCount: requiredNonnegativeInteger(ctx, requiredField(ctx, obj, "availableCount", joinFieldPath(fieldPath, "availableCount")), joinFieldPath(fieldPath, "availableCount")),
@@ -917,6 +917,54 @@ function validateGroupTruncationEntry(ctx, value, fieldPath) {
917
917
  truncated: requiredBoolean(ctx, requiredField(ctx, obj, "truncated", joinFieldPath(fieldPath, "truncated")), joinFieldPath(fieldPath, "truncated")),
918
918
  droppedCount: requiredNonnegativeInteger(ctx, requiredField(ctx, obj, "droppedCount", joinFieldPath(fieldPath, "droppedCount")), joinFieldPath(fieldPath, "droppedCount"))
919
919
  };
920
+ if (optionalField(obj, "droppedEvidenceIds") !== undefined) {
921
+ result.droppedEvidenceIds = requiredStringArray(ctx, obj.droppedEvidenceIds, joinFieldPath(fieldPath, "droppedEvidenceIds"));
922
+ }
923
+ if (optionalField(obj, "required") !== undefined)
924
+ result.required = optionalBoolean(ctx, obj.required, joinFieldPath(fieldPath, "required"));
925
+ if (optionalField(obj, "reservation") !== undefined)
926
+ result.reservation = optionalNumber(ctx, obj.reservation, joinFieldPath(fieldPath, "reservation"));
927
+ if (optionalField(obj, "initiallySelectedCount") !== undefined)
928
+ result.initiallySelectedCount = optionalNumber(ctx, obj.initiallySelectedCount, joinFieldPath(fieldPath, "initiallySelectedCount"));
929
+ if (optionalField(obj, "unusedReservationContributed") !== undefined)
930
+ result.unusedReservationContributed = optionalNumber(ctx, obj.unusedReservationContributed, joinFieldPath(fieldPath, "unusedReservationContributed"));
931
+ if (optionalField(obj, "borrowedCapacity") !== undefined)
932
+ result.borrowedCapacity = optionalNumber(ctx, obj.borrowedCapacity, joinFieldPath(fieldPath, "borrowedCapacity"));
933
+ if (optionalField(obj, "requiredOmittedCount") !== undefined)
934
+ result.requiredOmittedCount = optionalNumber(ctx, obj.requiredOmittedCount, joinFieldPath(fieldPath, "requiredOmittedCount"));
935
+ if (optionalField(obj, "optionalOmittedCount") !== undefined)
936
+ result.optionalOmittedCount = optionalNumber(ctx, obj.optionalOmittedCount, joinFieldPath(fieldPath, "optionalOmittedCount"));
937
+ if (optionalField(obj, "adequacyAffected") !== undefined)
938
+ result.adequacyAffected = optionalBoolean(ctx, obj.adequacyAffected, joinFieldPath(fieldPath, "adequacyAffected"));
939
+ if (optionalField(obj, "governingHardBound") !== undefined)
940
+ result.governingHardBound = optionalNumber(ctx, obj.governingHardBound, joinFieldPath(fieldPath, "governingHardBound"));
941
+ if (optionalField(obj, "aggregateCapacityUsed") !== undefined)
942
+ result.aggregateCapacityUsed = optionalNumber(ctx, obj.aggregateCapacityUsed, joinFieldPath(fieldPath, "aggregateCapacityUsed"));
943
+ if (optionalField(obj, "aggregateCapacityRemaining") !== undefined)
944
+ result.aggregateCapacityRemaining = optionalNumber(ctx, obj.aggregateCapacityRemaining, joinFieldPath(fieldPath, "aggregateCapacityRemaining"));
945
+ return result;
946
+ }
947
+ const ROLE_CONDITION_IDS = ["implementation.selected-owner", "implementation.required-contract"];
948
+ const ROLE_CONDITION_WITNESS_POLICIES = ["at-least-one"];
949
+ const ROLE_CONDITION_COVERAGE_LOSS_REASONS = ["bounded-allocation-omitted-required-witnesses"];
950
+ const ROLE_CONDITION_ROLES = ["architecture", "implementation", "test-implementation"];
951
+ export function validateRoleConditionCoverage(ctx, value, fieldPath) {
952
+ const obj = requiredObject(ctx, value, fieldPath);
953
+ return {
954
+ conditionId: requiredLiteral(ctx, requiredField(ctx, obj, "conditionId", joinFieldPath(fieldPath, "conditionId")), joinFieldPath(fieldPath, "conditionId"), ROLE_CONDITION_IDS),
955
+ role: requiredLiteral(ctx, requiredField(ctx, obj, "role", joinFieldPath(fieldPath, "role")), joinFieldPath(fieldPath, "role"), ROLE_CONDITION_ROLES),
956
+ required: requiredBoolean(ctx, requiredField(ctx, obj, "required", joinFieldPath(fieldPath, "required")), joinFieldPath(fieldPath, "required")),
957
+ evidenceGroupIds: requiredStringArray(ctx, requiredField(ctx, obj, "evidenceGroupIds", joinFieldPath(fieldPath, "evidenceGroupIds")), joinFieldPath(fieldPath, "evidenceGroupIds")),
958
+ witnessPolicy: requiredLiteral(ctx, requiredField(ctx, obj, "witnessPolicy", joinFieldPath(fieldPath, "witnessPolicy")), joinFieldPath(fieldPath, "witnessPolicy"), ROLE_CONDITION_WITNESS_POLICIES),
959
+ requiredWitnessCount: requiredNonnegativeInteger(ctx, requiredField(ctx, obj, "requiredWitnessCount", joinFieldPath(fieldPath, "requiredWitnessCount")), joinFieldPath(fieldPath, "requiredWitnessCount")),
960
+ availableWitnessCount: requiredNonnegativeInteger(ctx, requiredField(ctx, obj, "availableWitnessCount", joinFieldPath(fieldPath, "availableWitnessCount")), joinFieldPath(fieldPath, "availableWitnessCount")),
961
+ retainedWitnessCount: requiredNonnegativeInteger(ctx, requiredField(ctx, obj, "retainedWitnessCount", joinFieldPath(fieldPath, "retainedWitnessCount")), joinFieldPath(fieldPath, "retainedWitnessCount")),
962
+ retainedWitnessIds: requiredStringArray(ctx, requiredField(ctx, obj, "retainedWitnessIds", joinFieldPath(fieldPath, "retainedWitnessIds")), joinFieldPath(fieldPath, "retainedWitnessIds")),
963
+ conditionSatisfied: requiredBoolean(ctx, requiredField(ctx, obj, "conditionSatisfied", joinFieldPath(fieldPath, "conditionSatisfied")), joinFieldPath(fieldPath, "conditionSatisfied")),
964
+ lostRequiredCondition: requiredBoolean(ctx, requiredField(ctx, obj, "lostRequiredCondition", joinFieldPath(fieldPath, "lostRequiredCondition")), joinFieldPath(fieldPath, "lostRequiredCondition")),
965
+ lossReason: requiredNullableLiteral(ctx, requiredField(ctx, obj, "lossReason", joinFieldPath(fieldPath, "lossReason")), joinFieldPath(fieldPath, "lossReason"), ROLE_CONDITION_COVERAGE_LOSS_REASONS),
966
+ evaluationOrder: requiredNumber(ctx, requiredField(ctx, obj, "evaluationOrder", joinFieldPath(fieldPath, "evaluationOrder")), joinFieldPath(fieldPath, "evaluationOrder"))
967
+ };
920
968
  }
921
969
  export function validateProvenanceRecord(ctx, value, fieldPath) {
922
970
  const obj = requiredObject(ctx, value, fieldPath);
@@ -1040,11 +1088,15 @@ function validateCapsuleTruncationRecord(ctx, value, fieldPath) {
1040
1088
  }
1041
1089
  export function validateTruncationSummary(ctx, value, fieldPath) {
1042
1090
  const obj = requiredObject(ctx, value, fieldPath);
1043
- return {
1091
+ const result = {
1044
1092
  truncated: requiredBoolean(ctx, requiredField(ctx, obj, "truncated", joinFieldPath(fieldPath, "truncated")), joinFieldPath(fieldPath, "truncated")),
1045
1093
  records: requiredArray(ctx, requiredField(ctx, obj, "records", joinFieldPath(fieldPath, "records")), joinFieldPath(fieldPath, "records")).map((item, i) => validateCapsuleTruncationRecord(ctx, item, arrayFieldPath(joinFieldPath(fieldPath, "records"), i))),
1046
1094
  warnings: requiredStringArray(ctx, requiredField(ctx, obj, "warnings", joinFieldPath(fieldPath, "warnings")), joinFieldPath(fieldPath, "warnings"))
1047
1095
  };
1096
+ if (optionalField(obj, "requiredEvidenceLost") !== undefined) {
1097
+ result.requiredEvidenceLost = optionalBoolean(ctx, obj.requiredEvidenceLost, joinFieldPath(fieldPath, "requiredEvidenceLost"));
1098
+ }
1099
+ return result;
1048
1100
  }
1049
1101
  function validateFullFileFallbackRecord(ctx, value, fieldPath) {
1050
1102
  const obj = requiredObject(ctx, value, fieldPath);
@@ -1178,6 +1230,11 @@ export function validateMyDevKitContextCapsuleV1(value, sourcePath) {
1178
1230
  testInfrastructure: validateTestInfrastructureSummary(ctx, requiredField(ctx, value, "testInfrastructure", "testInfrastructure"), "testInfrastructure"),
1179
1231
  unresolvedItems: requiredArray(ctx, requiredField(ctx, value, "unresolvedItems", "unresolvedItems"), "unresolvedItems").map((item, i) => validateUnresolvedEvidenceItem(ctx, item, arrayFieldPath("unresolvedItems", i))),
1180
1232
  groupTruncation: requiredArray(ctx, requiredField(ctx, value, "groupTruncation", "groupTruncation"), "groupTruncation").map((item, i) => validateGroupTruncationEntry(ctx, item, arrayFieldPath("groupTruncation", i))),
1233
+ ...(optionalField(value, "roleConditionCoverage") !== undefined
1234
+ ? {
1235
+ roleConditionCoverage: requiredArray(ctx, value.roleConditionCoverage, "roleConditionCoverage").map((item, i) => validateRoleConditionCoverage(ctx, item, arrayFieldPath("roleConditionCoverage", i)))
1236
+ }
1237
+ : {}),
1181
1238
  responsibilityMappings: validateResponsibilityMappingSummary(ctx, requiredField(ctx, value, "responsibilityMappings", "responsibilityMappings"), "responsibilityMappings"),
1182
1239
  roleAdequacy: validateRoleAdequacyStatement(ctx, requiredField(ctx, value, "roleAdequacy", "roleAdequacy"), "roleAdequacy"),
1183
1240
  freshness: validateFreshnessSummary(ctx, requiredField(ctx, value, "freshness", "freshness"), "freshness"),
@@ -1,6 +1,6 @@
1
1
  import { parseSupportedMajorOneSchemaVersion } from "./schemaVersion.js";
2
2
  import { ArtifactValidationError, arrayFieldPath, joinFieldPath, optionalField, optionalString, requiredArray, requiredField, requiredLiteral, requiredObject, requiredRecord, requiredScalarLike, requiredString, requiredStringArray } from "./runtimeValidation.js";
3
- import { validateBudgetSummary, validateContextAdequacyStatement, validateContextCapsuleRequest, validateFreshnessSummary, validateFullFileFallbackSummary, validateProvenanceRecord, validateResponsibilityMappingSummary, validateRoleAdequacyStatement, validateRoleContextSummary, validateTruncationSummary } from "./validateMyDevKitContextCapsuleV1.js";
3
+ import { validateBudgetSummary, validateContextAdequacyStatement, validateContextCapsuleRequest, validateFreshnessSummary, validateFullFileFallbackSummary, validateProvenanceRecord, validateResponsibilityMappingSummary, validateRoleAdequacyStatement, validateRoleConditionCoverage, validateRoleContextSummary, validateTruncationSummary } from "./validateMyDevKitContextCapsuleV1.js";
4
4
  const ARTIFACT_KIND = "my-dev-kit-retrieval-audit-record-v1";
5
5
  const AUDIT_STEP_STATUSES = ["ok", "skipped", "failed"];
6
6
  function validateContextCapsuleTool(ctx, value, fieldPath) {
@@ -83,6 +83,11 @@ export function validateMyDevKitRetrievalAuditRecordV1(value, sourcePath) {
83
83
  contextAdequacy: validateContextAdequacyStatement(ctx, requiredField(ctx, value, "contextAdequacy", "contextAdequacy"), "contextAdequacy"),
84
84
  roleContext: validateRoleContextSummary(ctx, requiredField(ctx, value, "roleContext", "roleContext"), "roleContext"),
85
85
  responsibilityMappings: validateResponsibilityMappingSummary(ctx, requiredField(ctx, value, "responsibilityMappings", "responsibilityMappings"), "responsibilityMappings"),
86
+ ...(optionalField(value, "roleConditionCoverage") !== undefined
87
+ ? {
88
+ roleConditionCoverage: requiredArray(ctx, value.roleConditionCoverage, "roleConditionCoverage").map((item, i) => validateRoleConditionCoverage(ctx, item, arrayFieldPath("roleConditionCoverage", i)))
89
+ }
90
+ : {}),
86
91
  roleAdequacy: validateRoleAdequacyStatement(ctx, requiredField(ctx, value, "roleAdequacy", "roleAdequacy"), "roleAdequacy"),
87
92
  freshness: validateFreshnessSummary(ctx, requiredField(ctx, value, "freshness", "freshness"), "freshness"),
88
93
  budget: validateBudgetSummary(ctx, requiredField(ctx, value, "budget", "budget"), "budget"),
@@ -0,0 +1,177 @@
1
+ import { parseSupportedMajorOneSchemaVersion } from "./schemaVersion.js";
2
+ import { ArtifactValidationError, arrayFieldPath, joinFieldPath, optionalField, optionalString, requiredArray, requiredBoolean, requiredField, requiredLiteral, requiredNullableLiteral, requiredNullableString, requiredObject, requiredString, requiredStringArray } from "./runtimeValidation.js";
3
+ import { validateOrchestratorContextReadinessResultV1 } from "./orchestratorContextReadinessResultV1.js";
4
+ import { ARTIFACT_LIFECYCLE_STATES, CONTEXT_SENSITIVE_STAGE_NAMES, CORRECTABLE_STAGES, JUDGE_VERDICT_PARSE_STATUSES, JUDGE_VERDICTS, MANUAL_ARTIFACT_LIFECYCLE_STATES, ROUTE_STATUSES, RUN_INTEGRITY_READINESS_CLASSIFICATIONS } from "./orchestratorRunIntegrityV1.js";
5
+ const ARTIFACT_KIND = "orchestrator-run-integrity-evidence-v1";
6
+ const EXPECTED_JUDGE_VERDICTS = ["PASS", "NEED_CONTEXT"];
7
+ const APPLICABLE_CONTEXT_KINDS = ["implementation", "test"];
8
+ function validateContextReadinessNested(ctx, value, fieldPath) {
9
+ const result = validateOrchestratorContextReadinessResultV1(value, `${ctx.sourcePath}#${fieldPath}`);
10
+ if (!result.ok) {
11
+ throw new ArtifactValidationError({
12
+ ok: false,
13
+ artifactKind: ctx.artifactKind,
14
+ sourcePath: ctx.sourcePath,
15
+ code: result.code,
16
+ message: `Nested readiness field "${fieldPath}" is invalid: ${result.message}`,
17
+ fieldPath,
18
+ expected: result.expected,
19
+ actual: result.actual
20
+ });
21
+ }
22
+ return result.artifact;
23
+ }
24
+ function validateCorrectionRouteResult(ctx, value, fieldPath) {
25
+ const obj = requiredObject(ctx, value, fieldPath);
26
+ return {
27
+ verdict: requiredNullableLiteral(ctx, requiredField(ctx, obj, "verdict", joinFieldPath(fieldPath, "verdict")), joinFieldPath(fieldPath, "verdict"), JUDGE_VERDICTS),
28
+ recommendedStage: requiredNullableString(ctx, requiredField(ctx, obj, "recommendedStage", joinFieldPath(fieldPath, "recommendedStage")), joinFieldPath(fieldPath, "recommendedStage")),
29
+ routedStage: requiredNullableLiteral(ctx, requiredField(ctx, obj, "routedStage", joinFieldPath(fieldPath, "routedStage")), joinFieldPath(fieldPath, "routedStage"), CORRECTABLE_STAGES),
30
+ routeStatus: requiredLiteral(ctx, requiredField(ctx, obj, "routeStatus", joinFieldPath(fieldPath, "routeStatus")), joinFieldPath(fieldPath, "routeStatus"), ROUTE_STATUSES),
31
+ warnings: requiredStringArray(ctx, requiredField(ctx, obj, "warnings", joinFieldPath(fieldPath, "warnings")), joinFieldPath(fieldPath, "warnings")),
32
+ errors: requiredStringArray(ctx, requiredField(ctx, obj, "errors", joinFieldPath(fieldPath, "errors")), joinFieldPath(fieldPath, "errors")),
33
+ isBlocked: requiredBoolean(ctx, requiredField(ctx, obj, "isBlocked", joinFieldPath(fieldPath, "isBlocked")), joinFieldPath(fieldPath, "isBlocked")),
34
+ strictFail: requiredBoolean(ctx, requiredField(ctx, obj, "strictFail", joinFieldPath(fieldPath, "strictFail")), joinFieldPath(fieldPath, "strictFail"))
35
+ };
36
+ }
37
+ function validateGate(ctx, value, fieldPath) {
38
+ const obj = requiredObject(ctx, value, fieldPath);
39
+ const result = {
40
+ schemaVersion: requiredLiteral(ctx, requiredField(ctx, obj, "schemaVersion", joinFieldPath(fieldPath, "schemaVersion")), joinFieldPath(fieldPath, "schemaVersion"), ["1.0.0"]),
41
+ mode: requiredString(ctx, requiredField(ctx, obj, "mode", joinFieldPath(fieldPath, "mode")), joinFieldPath(fieldPath, "mode")),
42
+ contextRequired: requiredBoolean(ctx, requiredField(ctx, obj, "contextRequired", joinFieldPath(fieldPath, "contextRequired")), joinFieldPath(fieldPath, "contextRequired")),
43
+ applicableContextKinds: requiredArray(ctx, requiredField(ctx, obj, "applicableContextKinds", joinFieldPath(fieldPath, "applicableContextKinds")), joinFieldPath(fieldPath, "applicableContextKinds")).map((item, i) => requiredLiteral(ctx, item, arrayFieldPath(joinFieldPath(fieldPath, "applicableContextKinds"), i), APPLICABLE_CONTEXT_KINDS)),
44
+ contextReady: requiredBoolean(ctx, requiredField(ctx, obj, "contextReady", joinFieldPath(fieldPath, "contextReady")), joinFieldPath(fieldPath, "contextReady")),
45
+ readinessClassification: requiredLiteral(ctx, requiredField(ctx, obj, "readinessClassification", joinFieldPath(fieldPath, "readinessClassification")), joinFieldPath(fieldPath, "readinessClassification"), RUN_INTEGRITY_READINESS_CLASSIFICATIONS),
46
+ blockedStageNames: requiredArray(ctx, requiredField(ctx, obj, "blockedStageNames", joinFieldPath(fieldPath, "blockedStageNames")), joinFieldPath(fieldPath, "blockedStageNames")).map((item, i) => requiredLiteral(ctx, item, arrayFieldPath(joinFieldPath(fieldPath, "blockedStageNames"), i), CONTEXT_SENSITIVE_STAGE_NAMES)),
47
+ blockingCodes: requiredStringArray(ctx, requiredField(ctx, obj, "blockingCodes", joinFieldPath(fieldPath, "blockingCodes")), joinFieldPath(fieldPath, "blockingCodes")),
48
+ recommendedCorrectionStage: requiredNullableString(ctx, requiredField(ctx, obj, "recommendedCorrectionStage", joinFieldPath(fieldPath, "recommendedCorrectionStage")), joinFieldPath(fieldPath, "recommendedCorrectionStage")),
49
+ expectedJudgeVerdict: requiredLiteral(ctx, requiredField(ctx, obj, "expectedJudgeVerdict", joinFieldPath(fieldPath, "expectedJudgeVerdict")), joinFieldPath(fieldPath, "expectedJudgeVerdict"), EXPECTED_JUDGE_VERDICTS),
50
+ warnings: requiredStringArray(ctx, requiredField(ctx, obj, "warnings", joinFieldPath(fieldPath, "warnings")), joinFieldPath(fieldPath, "warnings"))
51
+ };
52
+ if (optionalField(obj, "implementationContext") !== undefined) {
53
+ result.implementationContext = validateContextReadinessNested(ctx, obj.implementationContext, joinFieldPath(fieldPath, "implementationContext"));
54
+ }
55
+ if (optionalField(obj, "testContext") !== undefined) {
56
+ result.testContext = validateContextReadinessNested(ctx, obj.testContext, joinFieldPath(fieldPath, "testContext"));
57
+ }
58
+ if (optionalField(obj, "primaryBlocker") !== undefined) {
59
+ // primaryBlocker reuses ContextReadinessBlockerSummary's exact shape (owned by
60
+ // orchestratorContextReadinessResultV1.ts's blockerSummary field); walked structurally
61
+ // here rather than re-validated through a second nested-artifact call, since it is not
62
+ // itself a standalone readiness artifact.
63
+ const blockerObj = requiredObject(ctx, obj.primaryBlocker, joinFieldPath(fieldPath, "primaryBlocker"));
64
+ result.primaryBlocker = blockerObj;
65
+ }
66
+ return result;
67
+ }
68
+ function validateJudgeIntegrity(ctx, value, fieldPath) {
69
+ const obj = requiredObject(ctx, value, fieldPath);
70
+ const result = {
71
+ schemaVersion: requiredLiteral(ctx, requiredField(ctx, obj, "schemaVersion", joinFieldPath(fieldPath, "schemaVersion")), joinFieldPath(fieldPath, "schemaVersion"), ["1.0.0"]),
72
+ judgeArtifactPresent: requiredBoolean(ctx, requiredField(ctx, obj, "judgeArtifactPresent", joinFieldPath(fieldPath, "judgeArtifactPresent")), joinFieldPath(fieldPath, "judgeArtifactPresent")),
73
+ judgeVerdictParseStatus: requiredLiteral(ctx, requiredField(ctx, obj, "judgeVerdictParseStatus", joinFieldPath(fieldPath, "judgeVerdictParseStatus")), joinFieldPath(fieldPath, "judgeVerdictParseStatus"), JUDGE_VERDICT_PARSE_STATUSES),
74
+ authoredJudgeVerdict: requiredNullableLiteral(ctx, requiredField(ctx, obj, "authoredJudgeVerdict", joinFieldPath(fieldPath, "authoredJudgeVerdict")), joinFieldPath(fieldPath, "authoredJudgeVerdict"), JUDGE_VERDICTS),
75
+ expectedJudgeVerdict: requiredLiteral(ctx, requiredField(ctx, obj, "expectedJudgeVerdict", joinFieldPath(fieldPath, "expectedJudgeVerdict")), joinFieldPath(fieldPath, "expectedJudgeVerdict"), EXPECTED_JUDGE_VERDICTS),
76
+ judgeVerdictMatchesExpected: requiredBoolean(ctx, requiredField(ctx, obj, "judgeVerdictMatchesExpected", joinFieldPath(fieldPath, "judgeVerdictMatchesExpected")), joinFieldPath(fieldPath, "judgeVerdictMatchesExpected")),
77
+ judgeVerdictAccepted: requiredBoolean(ctx, requiredField(ctx, obj, "judgeVerdictAccepted", joinFieldPath(fieldPath, "judgeVerdictAccepted")), joinFieldPath(fieldPath, "judgeVerdictAccepted")),
78
+ correctionRequired: requiredBoolean(ctx, requiredField(ctx, obj, "correctionRequired", joinFieldPath(fieldPath, "correctionRequired")), joinFieldPath(fieldPath, "correctionRequired")),
79
+ correctionBlocked: requiredBoolean(ctx, requiredField(ctx, obj, "correctionBlocked", joinFieldPath(fieldPath, "correctionBlocked")), joinFieldPath(fieldPath, "correctionBlocked")),
80
+ acceptedCorrectionStage: requiredNullableString(ctx, requiredField(ctx, obj, "acceptedCorrectionStage", joinFieldPath(fieldPath, "acceptedCorrectionStage")), joinFieldPath(fieldPath, "acceptedCorrectionStage")),
81
+ finalReportEligible: requiredBoolean(ctx, requiredField(ctx, obj, "finalReportEligible", joinFieldPath(fieldPath, "finalReportEligible")), joinFieldPath(fieldPath, "finalReportEligible")),
82
+ blockingCodes: requiredStringArray(ctx, requiredField(ctx, obj, "blockingCodes", joinFieldPath(fieldPath, "blockingCodes")), joinFieldPath(fieldPath, "blockingCodes")),
83
+ acceptedCorrectionRoute: (() => {
84
+ const routeValue = requiredField(ctx, obj, "acceptedCorrectionRoute", joinFieldPath(fieldPath, "acceptedCorrectionRoute"));
85
+ return routeValue === null ? null : validateCorrectionRouteResult(ctx, routeValue, joinFieldPath(fieldPath, "acceptedCorrectionRoute"));
86
+ })()
87
+ };
88
+ if (optionalField(obj, "primaryReason") !== undefined) {
89
+ result.primaryReason = optionalString(ctx, obj.primaryReason, joinFieldPath(fieldPath, "primaryReason"));
90
+ }
91
+ return result;
92
+ }
93
+ function validateFinalReportEligibility(ctx, value, fieldPath) {
94
+ const obj = requiredObject(ctx, value, fieldPath);
95
+ const result = {
96
+ eligible: requiredBoolean(ctx, requiredField(ctx, obj, "eligible", joinFieldPath(fieldPath, "eligible")), joinFieldPath(fieldPath, "eligible")),
97
+ contextReady: requiredBoolean(ctx, requiredField(ctx, obj, "contextReady", joinFieldPath(fieldPath, "contextReady")), joinFieldPath(fieldPath, "contextReady")),
98
+ priorArtifactsValid: requiredBoolean(ctx, requiredField(ctx, obj, "priorArtifactsValid", joinFieldPath(fieldPath, "priorArtifactsValid")), joinFieldPath(fieldPath, "priorArtifactsValid")),
99
+ judgeIntegrity: validateJudgeIntegrity(ctx, requiredField(ctx, obj, "judgeIntegrity", joinFieldPath(fieldPath, "judgeIntegrity")), joinFieldPath(fieldPath, "judgeIntegrity")),
100
+ blockingCodes: requiredStringArray(ctx, requiredField(ctx, obj, "blockingCodes", joinFieldPath(fieldPath, "blockingCodes")), joinFieldPath(fieldPath, "blockingCodes"))
101
+ };
102
+ if (optionalField(obj, "primaryReason") !== undefined) {
103
+ result.primaryReason = optionalString(ctx, obj.primaryReason, joinFieldPath(fieldPath, "primaryReason"));
104
+ }
105
+ return result;
106
+ }
107
+ function validateArtifactStateRecord(ctx, value, fieldPath) {
108
+ const obj = requiredObject(ctx, value, fieldPath);
109
+ const result = {
110
+ state: requiredLiteral(ctx, requiredField(ctx, obj, "state", joinFieldPath(fieldPath, "state")), joinFieldPath(fieldPath, "state"), MANUAL_ARTIFACT_LIFECYCLE_STATES),
111
+ updatedAt: requiredString(ctx, requiredField(ctx, obj, "updatedAt", joinFieldPath(fieldPath, "updatedAt")), joinFieldPath(fieldPath, "updatedAt"))
112
+ };
113
+ if (optionalField(obj, "reason") !== undefined)
114
+ result.reason = optionalString(ctx, obj.reason, joinFieldPath(fieldPath, "reason"));
115
+ if (optionalField(obj, "source") !== undefined)
116
+ result.source = optionalString(ctx, obj.source, joinFieldPath(fieldPath, "source"));
117
+ return result;
118
+ }
119
+ function validateLifecycleEntry(ctx, value, fieldPath) {
120
+ const obj = requiredObject(ctx, value, fieldPath);
121
+ const manualRecordValue = requiredField(ctx, obj, "manualRecord", joinFieldPath(fieldPath, "manualRecord"));
122
+ const result = {
123
+ artifactFile: requiredString(ctx, requiredField(ctx, obj, "artifactFile", joinFieldPath(fieldPath, "artifactFile")), joinFieldPath(fieldPath, "artifactFile")),
124
+ stageName: requiredString(ctx, requiredField(ctx, obj, "stageName", joinFieldPath(fieldPath, "stageName")), joinFieldPath(fieldPath, "stageName")),
125
+ fileExists: requiredBoolean(ctx, requiredField(ctx, obj, "fileExists", joinFieldPath(fieldPath, "fileExists")), joinFieldPath(fieldPath, "fileExists")),
126
+ manualRecord: manualRecordValue === null ? null : validateArtifactStateRecord(ctx, manualRecordValue, joinFieldPath(fieldPath, "manualRecord")),
127
+ resolvedState: requiredLiteral(ctx, requiredField(ctx, obj, "resolvedState", joinFieldPath(fieldPath, "resolvedState")), joinFieldPath(fieldPath, "resolvedState"), ARTIFACT_LIFECYCLE_STATES)
128
+ };
129
+ if (optionalField(obj, "blockingReason") !== undefined) {
130
+ result.blockingReason = optionalString(ctx, obj.blockingReason, joinFieldPath(fieldPath, "blockingReason"));
131
+ }
132
+ return result;
133
+ }
134
+ export function validateOrchestratorRunIntegrityEvidenceV1(value, sourcePath) {
135
+ const ctx = { artifactKind: ARTIFACT_KIND, sourcePath };
136
+ try {
137
+ const schemaVersionResult = parseSupportedMajorOneSchemaVersion(requiredField(ctx, value, "schemaVersion", "schemaVersion"), ARTIFACT_KIND, sourcePath);
138
+ if ("ok" in schemaVersionResult)
139
+ return schemaVersionResult;
140
+ const evidence = {
141
+ schemaVersion: requiredString(ctx, value.schemaVersion, "schemaVersion"),
142
+ runFolder: requiredString(ctx, requiredField(ctx, value, "runFolder", "runFolder"), "runFolder"),
143
+ gate: validateGate(ctx, requiredField(ctx, value, "gate", "gate"), "gate"),
144
+ lifecycle: requiredArray(ctx, requiredField(ctx, value, "lifecycle", "lifecycle"), "lifecycle").map((item, i) => validateLifecycleEntry(ctx, item, arrayFieldPath("lifecycle", i)))
145
+ };
146
+ if (optionalField(value, "judgeIntegrity") !== undefined) {
147
+ evidence.judgeIntegrity = validateJudgeIntegrity(ctx, value.judgeIntegrity, "judgeIntegrity");
148
+ }
149
+ if (optionalField(value, "finalReportEligibility") !== undefined) {
150
+ evidence.finalReportEligibility = validateFinalReportEligibility(ctx, value.finalReportEligibility, "finalReportEligibility");
151
+ }
152
+ if (optionalField(value, "finalArtifactPresent") !== undefined) {
153
+ evidence.finalArtifactPresent = requiredBoolean(ctx, value.finalArtifactPresent, "finalArtifactPresent");
154
+ }
155
+ if (optionalField(value, "finalArtifactVerdict") !== undefined) {
156
+ evidence.finalArtifactVerdict = requiredNullableLiteral(ctx, value.finalArtifactVerdict, "finalArtifactVerdict", JUDGE_VERDICTS);
157
+ }
158
+ // Per the exact-mirror contract, the returned artifact is always the original parsed
159
+ // reference, not a rebuilt object. The construction above exists only to walk and
160
+ // type-check every field.
161
+ void evidence;
162
+ return {
163
+ ok: true,
164
+ artifactKind: ARTIFACT_KIND,
165
+ sourcePath,
166
+ schemaVersion: value.schemaVersion,
167
+ schemaMajor: 1,
168
+ artifact: value,
169
+ rawArtifact: value
170
+ };
171
+ }
172
+ catch (error) {
173
+ if (error instanceof ArtifactValidationError)
174
+ return error.failure;
175
+ throw error;
176
+ }
177
+ }
@@ -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
+ }