@dailephd/my-dev-kit-lab 0.4.4 → 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 (74) hide show
  1. package/CHANGELOG.md +468 -0
  2. package/README.md +3 -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/stageContextMetrics/calculateAllocationMetrics.js +169 -0
  10. package/dist/src/evaluation/stageContextMetrics/calculateConditionCoverageMetrics.js +74 -0
  11. package/dist/src/evaluation/stageContextMetrics/calculateProducerConditionAgreement.js +113 -0
  12. package/dist/src/evaluation/stageContextMetrics/calculateReadinessAgreement.js +60 -0
  13. package/dist/src/evaluation/stageContextMetrics/calculateRunIntegrityAgreement.js +309 -0
  14. package/dist/src/evaluation/stageContextMetrics/calculateSupplementalRawAgreement.js +12 -2
  15. package/dist/src/evaluation/stageContextMetrics/calculateTruncationClassification.js +100 -0
  16. package/dist/src/evaluation/stageContextMetrics/evaluateProducerReadinessBridge.js +76 -5
  17. package/dist/src/evaluation/stageContextMetrics/index.js +4 -0
  18. package/dist/src/evaluation/stageContextMetrics/runIntegrityAgreementTypes.js +1 -0
  19. package/dist/src/evaluation/stageContextSelectors/contextArtifactConsistency.js +7 -0
  20. package/dist/src/evaluation/stageContextSelectors/index.js +1 -0
  21. package/dist/src/evaluation/stageContextSelectors/orchestratorRunIntegritySelectors.js +64 -0
  22. package/dist/src/evaluation/upstreamArtifacts/index.js +2 -0
  23. package/dist/src/evaluation/upstreamArtifacts/orchestratorRunIntegrityV1.js +33 -0
  24. package/dist/src/evaluation/upstreamArtifacts/readOrchestratorRunIntegrityV1.js +9 -0
  25. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitContextCapsuleV1.js +59 -2
  26. package/dist/src/evaluation/upstreamArtifacts/validateMyDevKitRetrievalAuditRecordV1.js +6 -1
  27. package/dist/src/evaluation/upstreamArtifacts/validateOrchestratorRunIntegrityV1.js +177 -0
  28. package/dist/src/report/experiments/buildContextIntegrityReport.js +204 -0
  29. package/dist/src/report/experiments/contextIntegrityReportModel.js +1 -0
  30. package/dist/src/report/experiments/index.js +5 -0
  31. package/dist/src/report/experiments/renderContextIntegrityHtml.js +98 -0
  32. package/dist/src/report/experiments/renderContextIntegrityJsonReport.js +3 -0
  33. package/dist/src/report/experiments/renderContextIntegrityText.js +111 -0
  34. package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +33 -0
  35. package/dist/src/securityValidation/packageChecks/runPackageChecks.js +11 -5
  36. package/docs/METRICS.md +83 -0
  37. package/package.json +4 -2
  38. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/derived/run-integrity-evidence.json +99 -0
  39. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-audit.json +1585 -0
  40. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-capsule.json +11455 -0
  41. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/00-request.txt +1 -0
  42. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/architecture-context-packet.txt +82 -0
  43. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/behavior-model.txt +104 -0
  44. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/final-report.txt +41 -0
  45. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-context-packet.txt +114 -0
  46. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-report.txt +92 -0
  47. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/judge-report.txt +34 -0
  48. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/pseudocode-packet.txt +244 -0
  49. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/request-brief.txt +40 -0
  50. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-context-packet.txt +93 -0
  51. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-implementation-report.txt +69 -0
  52. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-strategy-packet.txt +354 -0
  53. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/verification-report.txt +85 -0
  54. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/derived/run-integrity-evidence.json +98 -0
  55. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-audit.json +1169 -0
  56. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-request.json +29 -0
  57. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-audit.json +1494 -0
  58. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-capsule.json +11364 -0
  59. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-request.json +33 -0
  60. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/test-request.json +74 -0
  61. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/architecture-context-retrieval-report.txt +58 -0
  62. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/implementation-context-retrieval-report.txt +75 -0
  63. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/test-context-retrieval-report.txt +84 -0
  64. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/run.json +62 -0
  65. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/my-dev-kit-version.txt +1 -0
  66. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/orchestrator-version.txt +1 -0
  67. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/corrected-replay-manifest.json +19 -0
  68. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/failed-run-manifest.json +56 -0
  69. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/PROVENANCE.txt +18 -0
  70. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/context-capsule/complete-v1.0.0.json +556 -0
  71. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/retrieval-audit-record/complete-v1.0.0.json +238 -0
  72. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/PROVENANCE.txt +31 -0
  73. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/ready-pass-final-pass.json +132 -0
  74. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/refresh-required-need-context.json +146 -0
@@ -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
+ }