rea-agents 2.4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -19
- package/bridge/ghidra/ReaGhidraBridge.java +524 -4
- package/bridge/hopper_bridge.py +313 -28
- package/dist/application/AnalysisClientCleanup.js +14 -0
- package/dist/application/AnalysisContextQueries.js +130 -0
- package/dist/application/AnalysisSnapshotCache.js +4 -2
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
- package/dist/application/ArtifactInventory/scanCanonical.js +1 -1
- package/dist/application/BinarySession.js +20 -8
- package/dist/application/BinarySessionComposition.js +21 -0
- package/dist/application/BinarySessionRecords.js +79 -9
- package/dist/application/BinarySessionStatus.js +31 -1
- package/dist/application/BrowserEvidence.js +14 -0
- package/dist/application/BrowserScenarioCapturePort.js +1 -0
- package/dist/application/BrowserScenarioCaptureService.js +53 -0
- package/dist/application/BrowserScenarioEvidence.js +40 -0
- package/dist/application/CallPathTracing.js +160 -0
- package/dist/application/CapabilityInventory.js +84 -14
- package/dist/application/ClientRegistrationStatus.js +4 -1
- package/dist/application/CompositeProvider.js +10 -1
- package/dist/application/DirectAnalysis.js +13 -4
- package/dist/application/EnhancedLiteralTracing.js +118 -0
- package/dist/application/EnhancedTools.js +71 -127
- package/dist/application/EvidenceLedger.js +45 -16
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
- package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
- package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
- package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
- package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
- package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
- package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
- package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
- package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
- package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
- package/dist/application/LazyAnalysisProvider.js +77 -0
- package/dist/application/LoopbackReplay.js +1 -1
- package/dist/application/NativeApiInspection.js +80 -0
- package/dist/application/ProcessReactiveEffects.js +6 -0
- package/dist/application/ProcessReactiveHarness.js +16 -1
- package/dist/application/ProjectPermissionStore.js +1 -0
- package/dist/application/ReconstructionObligationAuthority.js +72 -0
- package/dist/application/ReconstructionObligationCandidates.js +265 -0
- package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
- package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
- package/dist/application/ReconstructionObligationLedgerService.js +72 -0
- package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
- package/dist/application/ReconstructionObligationPolicies.js +132 -0
- package/dist/application/ReconstructionReadinessService.js +48 -0
- package/dist/application/SessionProviderRouter.js +6 -6
- package/dist/application/SetupClientConfiguration.js +4 -2
- package/dist/application/runtime.js +26 -9
- package/dist/artifacts/ArtifactProvider.js +87 -22
- package/dist/browser/BrowserScenarioSecrets.js +53 -0
- package/dist/browser/BrowserScenarioSessionPort.js +1 -0
- package/dist/browser/CdpBrowserProvider.js +2 -2
- package/dist/browser/CdpCaptureDocuments.js +57 -0
- package/dist/browser/CdpCaptureStorage.js +71 -29
- package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
- package/dist/browser/CdpEndpoint.js +8 -6
- package/dist/browser/CdpPageCapture.js +2 -0
- package/dist/browser/JavaScriptRuntimeScope.js +38 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +259 -0
- package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
- package/dist/browser/PlaywrightScenarioActions.js +62 -0
- package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
- package/dist/browser/PlaywrightScenarioEvents.js +301 -0
- package/dist/browser/PlaywrightScenarioSession.js +300 -0
- package/dist/browser/V8InspectorCaptureProjection.js +110 -0
- package/dist/browser/V8InspectorEndpoint.js +72 -0
- package/dist/browser/V8InspectorProvider.js +267 -0
- package/dist/catalogIdentity.js +11 -3
- package/dist/cli/artifactCommands.js +44 -3
- package/dist/cli/coreAnalysisCommands.js +78 -0
- package/dist/cli.js +4 -0
- package/dist/cliApplicationCommands.js +30 -2
- package/dist/cliBrowserAdvancedCommands.js +17 -5
- package/dist/cliBrowserCommands.js +1 -0
- package/dist/cliBrowserScenarioCommands.js +43 -0
- package/dist/cliCommandNames.js +9 -0
- package/dist/cliJavaScriptRuntimeCommands.js +164 -0
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliPolicyCommands.js +1 -0
- package/dist/config/environment.js +12 -0
- package/dist/config/parseConfig.js +88 -17
- package/dist/contracts/analysisSearchContract.js +14 -0
- package/dist/contracts/applicationToolContracts.js +86 -2
- package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
- package/dist/contracts/artifactToolContracts.js +29 -2
- package/dist/contracts/browserProviderToolContracts.js +7 -0
- package/dist/contracts/browserScenarioToolContracts.js +81 -0
- package/dist/contracts/browserToolContracts.js +88 -98
- package/dist/contracts/enhancedInputs.js +35 -6
- package/dist/contracts/functionInstructionContract.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +30 -0
- package/dist/contracts/hopperMemoryContracts.js +22 -0
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
- package/dist/contracts/promptContracts.js +14 -15
- package/dist/contracts/reconstructionReadinessExample.js +436 -0
- package/dist/contracts/toolContractExamples.js +8 -0
- package/dist/contracts/toolContractTypes.js +1 -0
- package/dist/contracts/toolContracts.js +34 -25
- package/dist/contracts/toolEffects.js +25 -0
- package/dist/contracts/toolOutputSchemaGroups.js +120 -30
- package/dist/contracts/toolOutputSchemaPrimitives.js +37 -0
- package/dist/domain/analysisErrorPresentation.js +8 -2
- package/dist/domain/analysisErrorProjection.js +9 -0
- package/dist/domain/artifactInspection.js +347 -0
- package/dist/domain/browserCaptureComparison.js +82 -0
- package/dist/domain/browserObservation.js +8 -1
- package/dist/domain/browserObservationErrors.js +1 -0
- package/dist/domain/browserObservationSchemas.js +26 -0
- package/dist/domain/browserScenario.js +165 -0
- package/dist/domain/browserScenarioCapture.js +57 -0
- package/dist/domain/browserScenarioCaptureValues.js +204 -0
- package/dist/domain/browserScenarioDiff.js +324 -0
- package/dist/domain/browserScenarioDiffValues.js +157 -0
- package/dist/domain/browserScenarioNormalization.js +45 -0
- package/dist/domain/browserScenarioValues.js +372 -0
- package/dist/domain/bytecodeProvider.js +179 -0
- package/dist/domain/conformancePackage.js +169 -0
- package/dist/domain/conformanceReplay.js +104 -0
- package/dist/domain/conformanceTrustGate.js +193 -0
- package/dist/domain/customProtocolCapture.js +137 -0
- package/dist/domain/eventProcessTree.js +214 -0
- package/dist/domain/evidenceBundle.js +47 -0
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +14 -1
- package/dist/domain/inputIssueProjection.js +7 -1
- package/dist/domain/javascriptRuntimeObservation.js +170 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
- package/dist/domain/javascriptSemanticAnalysis.js +13 -16
- package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
- package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
- package/dist/domain/javascriptSemanticDataEffects.js +284 -0
- package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
- package/dist/domain/javascriptSemanticFingerprints.js +174 -0
- package/dist/domain/javascriptSemanticIr.js +21 -1
- package/dist/domain/javascriptSemanticObjects.js +115 -0
- package/dist/domain/javascriptSemanticPromises.js +290 -0
- package/dist/domain/javascriptSemanticResources.js +136 -0
- package/dist/domain/javascriptSourceParser.js +15 -0
- package/dist/domain/javascriptStaticAnalysis.js +12 -15
- package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
- package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
- package/dist/domain/mobileApplicationInvestigation.js +159 -0
- package/dist/domain/nativeApiBoundary.js +130 -0
- package/dist/domain/objcSwiftMetadata.js +150 -0
- package/dist/domain/packageAnalysis.js +123 -0
- package/dist/domain/peInspection.js +196 -0
- package/dist/domain/processCapture.js +8 -2
- package/dist/domain/processReactiveScenario.js +1 -0
- package/dist/domain/processReactiveTransition.js +9 -4
- package/dist/domain/protocolCapture.js +243 -0
- package/dist/domain/providerCleanupError.js +11 -0
- package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
- package/dist/domain/reconstructionReadiness.js +121 -0
- package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
- package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
- package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
- package/dist/domain/reconstructionReadinessSchemas.js +240 -0
- package/dist/domain/sourceToBundleComparison.js +335 -0
- package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
- package/dist/domain/sourceToBundleSignals.js +202 -0
- package/dist/domain/webCaptureDiff.js +141 -27
- package/dist/domain/webScreenshot.js +1 -1
- package/dist/dotnet/ManagedStaticProvider.js +34 -5
- package/dist/generatedMcpToolCatalog.js +37 -0
- package/dist/generatedPackageMetadata.js +4 -4
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +40 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +47 -38
- package/dist/hopper/HopperCleanup.js +158 -0
- package/dist/hopper/HopperClient.js +93 -99
- package/dist/hopper/HopperProvider.js +61 -30
- package/dist/hopper/HopperRequestQueue.js +215 -0
- package/dist/hopper/HopperResponseStream.js +46 -0
- package/dist/hopper/protocol.js +63 -20
- package/dist/main/transport.js +24 -27
- package/dist/main.js +14 -6
- package/dist/mcpDoctor.js +27 -4
- package/dist/mcpStartupPolicy.js +14 -0
- package/dist/process/ProcessCommandIdentity.js +19 -0
- package/dist/process/ProcessOwnership.js +11 -8
- package/dist/server/DynamicToolAvailability.js +70 -0
- package/dist/server/LazyToolCatalog.js +134 -0
- package/dist/server/createServer.js +92 -154
- package/dist/server/hydrateServerTools.js +191 -0
- package/dist/server/lifecycleProgress.js +10 -0
- package/dist/server/permissionFailure.js +12 -0
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
- package/dist/server/registerApplicationTools/helpers.js +11 -7
- package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
- package/dist/server/registerApplicationTools/readiness.js +55 -0
- package/dist/server/registerApplicationTools.js +6 -0
- package/dist/server/registerArtifactTools.js +9 -1
- package/dist/server/registerBrowserScenarioTool.js +25 -0
- package/dist/server/registerBrowserTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +57 -0
- package/dist/server/registerEnhancedTools.js +28 -7
- package/dist/server/registerEvidenceResources.js +54 -101
- package/dist/server/registerEvidenceTools.js +9 -2
- package/dist/server/registerInvestigationTools.js +1 -2
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
- package/dist/server/registerReconstructionObligationLedgerResource.js +32 -0
- package/dist/server/registerReconstructionReadinessResource.js +32 -0
- package/dist/server/registerSessionRecordTools.js +82 -12
- package/dist/server/registerSessionStatusTool.js +11 -8
- package/dist/server/registerSessionTools.js +32 -58
- package/dist/server/sessionAvailabilityPolicy.js +10 -8
- package/dist/server/toolRegistrationOptions.js +21 -6
- package/dist/server/toolResult.js +12 -0
- package/package.json +28 -11
- package/scripts/package-runner-bootstrap.mjs +72 -0
- package/scripts/rea.mjs +11 -1
- package/skills/reverse-engineer-anything/SKILL.md +10 -3
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { addMissingEvidenceFindings, readinessFinding as finding, } from "./reconstructionReadinessFindingHelpers.js";
|
|
2
|
+
export const readinessIntegrityFindings = (input, evidenceIds, sourceDigest) => [
|
|
3
|
+
...comparisonFindings(input, evidenceIds),
|
|
4
|
+
...contradictionFindings(input, evidenceIds),
|
|
5
|
+
...closureFindings(input, evidenceIds),
|
|
6
|
+
...cleanupFindings(input, evidenceIds),
|
|
7
|
+
...replayFindings(input, evidenceIds, sourceDigest),
|
|
8
|
+
];
|
|
9
|
+
const comparisonFindings = (input, evidenceIds) => {
|
|
10
|
+
const findings = [];
|
|
11
|
+
for (const comparison of input.comparisons) {
|
|
12
|
+
const unsafeEquivalent = comparison.verdict === "equivalent" &&
|
|
13
|
+
(comparison.truncated ||
|
|
14
|
+
comparison.unavailable_authority ||
|
|
15
|
+
comparison.unstable ||
|
|
16
|
+
comparison.contradiction_ids.length > 0);
|
|
17
|
+
if (unsafeEquivalent)
|
|
18
|
+
findings.push(finding("false-equivalence", "compare-authority-candidate", "fail", `${comparison.comparison_id} claims equivalence across incomplete or contradicted Evidence.`, comparison.evidence_ids));
|
|
19
|
+
if (comparison.concurrent &&
|
|
20
|
+
comparison.schedule_semantics === "total-order")
|
|
21
|
+
findings.push(finding("unsafe-concurrency-semantics", "compare-authority-candidate", "fail", `${comparison.comparison_id} uses total-order semantics for concurrent behavior.`, comparison.evidence_ids));
|
|
22
|
+
if (comparison.deliberate_divergence_ref !== null &&
|
|
23
|
+
!comparison.divergence_refs.includes(comparison.deliberate_divergence_ref))
|
|
24
|
+
findings.push(finding("divergence-not-localized", "compare-authority-candidate", "fail", `${comparison.comparison_id} did not localize its deliberate primary divergence.`, comparison.evidence_ids));
|
|
25
|
+
addMissingEvidenceFindings(findings, "compare-authority-candidate", comparison.evidence_ids, evidenceIds);
|
|
26
|
+
}
|
|
27
|
+
return findings;
|
|
28
|
+
};
|
|
29
|
+
const contradictionFindings = (input, evidenceIds) => {
|
|
30
|
+
const findings = [];
|
|
31
|
+
const comparisons = new Map(input.comparisons.map((comparison) => [
|
|
32
|
+
comparison.comparison_id,
|
|
33
|
+
comparison,
|
|
34
|
+
]));
|
|
35
|
+
for (const contradiction of input.contradictions) {
|
|
36
|
+
if (contradiction.declared_sha256 === contradiction.observed_sha256 ||
|
|
37
|
+
new Set(contradiction.evidence_ids).size < 2)
|
|
38
|
+
findings.push(finding("contradiction-proof-incomplete", "preserve-contradictions", "fail", `${contradiction.contradiction_id} must preserve distinct hashes and Evidence records.`, contradiction.evidence_ids));
|
|
39
|
+
for (const comparisonId of contradiction.affected_comparison_ids) {
|
|
40
|
+
const comparison = comparisons.get(comparisonId);
|
|
41
|
+
if (comparison === undefined)
|
|
42
|
+
findings.push(finding("contradiction-comparison-missing", "preserve-contradictions", "unknown", `Contradiction references missing comparison ${comparisonId}.`, contradiction.evidence_ids));
|
|
43
|
+
else if (comparison.verdict === "equivalent" ||
|
|
44
|
+
!comparison.contradiction_ids.includes(contradiction.contradiction_id))
|
|
45
|
+
findings.push(finding("contradiction-equivalence-not-blocked", "preserve-contradictions", "fail", `${comparisonId} does not preserve contradiction ${contradiction.contradiction_id}.`, contradiction.evidence_ids));
|
|
46
|
+
}
|
|
47
|
+
addMissingEvidenceFindings(findings, "preserve-contradictions", contradiction.evidence_ids, evidenceIds);
|
|
48
|
+
}
|
|
49
|
+
return findings;
|
|
50
|
+
};
|
|
51
|
+
const closureFindings = (input, evidenceIds) => {
|
|
52
|
+
const findings = [];
|
|
53
|
+
if (input.obligation_ledger.summary.required === 0)
|
|
54
|
+
findings.push(finding("reconstruction-obligations-empty", "verify-reconstruction-closure", "unknown", "A ready ledger must include at least one required reconstruction obligation."));
|
|
55
|
+
if (input.obligation_ledger.status !== "ready" ||
|
|
56
|
+
input.obligation_ledger.summary.required_open > 0)
|
|
57
|
+
findings.push(finding("reconstruction-closure-open", "verify-reconstruction-closure", "unknown", `Obligation ledger is ${input.obligation_ledger.status} with ${String(input.obligation_ledger.summary.required_open)} required obligations open.`, input.obligation_ledger.evidence_links));
|
|
58
|
+
addMissingEvidenceFindings(findings, "verify-reconstruction-closure", input.obligation_ledger.evidence_links, evidenceIds);
|
|
59
|
+
evaluateClosureHistory(input, findings, evidenceIds);
|
|
60
|
+
for (const check of input.delegation_checks) {
|
|
61
|
+
if (check.delegates_to_authority)
|
|
62
|
+
findings.push(finding("candidate-delegates-to-authority", "verify-reconstruction-closure", "fail", `${check.candidate_id} delegates behavior back to the authority.`, check.evidence_ids));
|
|
63
|
+
addMissingEvidenceFindings(findings, "verify-reconstruction-closure", check.evidence_ids, evidenceIds);
|
|
64
|
+
}
|
|
65
|
+
return findings;
|
|
66
|
+
};
|
|
67
|
+
const evaluateClosureHistory = (input, findings, evidenceIds) => {
|
|
68
|
+
const history = [...input.closure_history].sort((left, right) => left.sequence - right.sequence);
|
|
69
|
+
if (new Set(history.map(({ sequence }) => sequence)).size !== history.length ||
|
|
70
|
+
history.at(-1)?.ledger_digest !== input.obligation_ledger.closure_digest)
|
|
71
|
+
findings.push(finding("closure-history-identity-mismatch", "verify-reconstruction-closure", "fail", "Closure history sequences must be unique and end at the supplied ledger digest."));
|
|
72
|
+
if (history[0]?.required_open === 0 ||
|
|
73
|
+
history.at(-1)?.required_open !== 0 ||
|
|
74
|
+
history.at(-1)?.status !== "ready")
|
|
75
|
+
findings.push(finding("incremental-closure-history-missing", "verify-reconstruction-closure", "unknown", "Closure history must begin partial and end ready with zero required obligations open."));
|
|
76
|
+
for (const [index, observation] of history.entries()) {
|
|
77
|
+
const previous = history[index - 1];
|
|
78
|
+
if (previous !== undefined &&
|
|
79
|
+
(observation.required_open > previous.required_open ||
|
|
80
|
+
observation.newly_verified_obligation_ids.length !==
|
|
81
|
+
previous.required_open - observation.required_open))
|
|
82
|
+
findings.push(finding("invalid-obligation-closure-transition", "verify-reconstruction-closure", "fail", `Closure observation ${String(observation.sequence)} does not match its newly verified obligations.`, observation.evidence_ids));
|
|
83
|
+
if (observation.newly_verified_obligation_ids.some((obligationId) => !input.obligation_ledger.obligations.some(({ obligation_id: candidateId, status }) => candidateId === obligationId && status === "verified")))
|
|
84
|
+
findings.push(finding("closure-obligation-proof-missing", "verify-reconstruction-closure", "fail", `Closure observation ${String(observation.sequence)} names an obligation without verified ledger proof.`, observation.evidence_ids));
|
|
85
|
+
addMissingEvidenceFindings(findings, "verify-reconstruction-closure", observation.evidence_ids, evidenceIds);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const cleanupFindings = (input, evidenceIds) => {
|
|
89
|
+
const findings = [];
|
|
90
|
+
for (const cleanup of input.cleanup) {
|
|
91
|
+
if (cleanup.owned_resources_remaining > 0)
|
|
92
|
+
findings.push(finding("owned-resource-leak", "reactive-scenarios", "fail", `${cleanup.run_id} retained ${String(cleanup.owned_resources_remaining)} owned resources.`, cleanup.diagnostic_evidence_ids));
|
|
93
|
+
if (cleanup.cancelled && cleanup.diagnostic_evidence_ids.length === 0)
|
|
94
|
+
findings.push(finding("cancelled-diagnostic-evidence-missing", "reactive-scenarios", "unknown", `${cleanup.run_id} cancellation retained no diagnostic Evidence.`));
|
|
95
|
+
addMissingEvidenceFindings(findings, "reactive-scenarios", cleanup.diagnostic_evidence_ids, evidenceIds);
|
|
96
|
+
}
|
|
97
|
+
for (const grant of input.grants) {
|
|
98
|
+
if (["denied", "cancelled"].includes(grant.decision) &&
|
|
99
|
+
grant.launched_process)
|
|
100
|
+
findings.push(finding("denied-authority-launched-process", "acquire-authority", "fail", `${grant.grant_id} launched a process after ${grant.decision}.`, grant.evidence_ids));
|
|
101
|
+
addMissingEvidenceFindings(findings, "acquire-authority", grant.evidence_ids, evidenceIds);
|
|
102
|
+
}
|
|
103
|
+
return findings;
|
|
104
|
+
};
|
|
105
|
+
const replayFindings = (input, evidenceIds, sourceDigest) => {
|
|
106
|
+
const findings = [];
|
|
107
|
+
if (!input.replay.deterministic)
|
|
108
|
+
findings.push(finding("replay-nondeterministic", "export-replay", "fail", "Clean replay did not reproduce the same semantic report.", input.replay.evidence_ids));
|
|
109
|
+
if (!input.replay.tamper_detected)
|
|
110
|
+
findings.push(finding("tamper-not-detected", "export-replay", "fail", "The conformance replay did not reject a tampered input.", input.replay.evidence_ids));
|
|
111
|
+
if (!input.replay.stale_input_detected)
|
|
112
|
+
findings.push(finding("stale-input-not-detected", "export-replay", "fail", "The conformance replay did not reject a stale digest.", input.replay.evidence_ids));
|
|
113
|
+
if (input.replay.expected_source_digest !== null &&
|
|
114
|
+
input.replay.expected_source_digest !== sourceDigest)
|
|
115
|
+
findings.push(finding("replay-source-digest-mismatch", "export-replay", "fail", `Expected ${input.replay.expected_source_digest}; observed ${sourceDigest}.`, input.replay.evidence_ids));
|
|
116
|
+
addMissingEvidenceFindings(findings, "export-replay", input.replay.evidence_ids, evidenceIds);
|
|
117
|
+
return findings;
|
|
118
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { addMissingEvidenceFindings, readinessFinding as finding, } from "./reconstructionReadinessFindingHelpers.js";
|
|
2
|
+
import { readinessStageIdSchema, } from "./reconstructionReadinessSchemas.js";
|
|
3
|
+
export const READINESS_REQUIRED_CHECKS = {
|
|
4
|
+
"discover-classify": [
|
|
5
|
+
"target-free-start",
|
|
6
|
+
"artifact-inventory",
|
|
7
|
+
"compatible-workflow-selected",
|
|
8
|
+
"limits-visible",
|
|
9
|
+
],
|
|
10
|
+
"diagnose-environment": [
|
|
11
|
+
"broken-runtime-distinguished",
|
|
12
|
+
"version-skew-detected",
|
|
13
|
+
"revision-changed-after-recovery",
|
|
14
|
+
],
|
|
15
|
+
"acquire-authority": [
|
|
16
|
+
"missing-scope-reported",
|
|
17
|
+
"narrow-grant-resumed",
|
|
18
|
+
"expansion-reprompted",
|
|
19
|
+
"denial-launched-nothing",
|
|
20
|
+
],
|
|
21
|
+
"static-analysis": [
|
|
22
|
+
"native-routed",
|
|
23
|
+
"javascript-routed",
|
|
24
|
+
"unknowns-preserved",
|
|
25
|
+
],
|
|
26
|
+
"reactive-scenarios": [
|
|
27
|
+
"predicate-driven",
|
|
28
|
+
"descendant-settled",
|
|
29
|
+
"electron-correlated",
|
|
30
|
+
"cancel-cleanup-preserved-evidence",
|
|
31
|
+
],
|
|
32
|
+
"compare-authority-candidate": [
|
|
33
|
+
"partial-order-accepted",
|
|
34
|
+
"divergence-localized",
|
|
35
|
+
"incomplete-is-unknown",
|
|
36
|
+
],
|
|
37
|
+
"preserve-contradictions": [
|
|
38
|
+
"record-and-continue",
|
|
39
|
+
"affected-equivalence-blocked",
|
|
40
|
+
"unaffected-comparison-continued",
|
|
41
|
+
],
|
|
42
|
+
"verify-reconstruction-closure": [
|
|
43
|
+
"incomplete-detected",
|
|
44
|
+
"incremental-verifier-closure",
|
|
45
|
+
"delegation-rejected",
|
|
46
|
+
],
|
|
47
|
+
"export-replay": [
|
|
48
|
+
"cli-mcp-parity",
|
|
49
|
+
"failure-status-parity",
|
|
50
|
+
"deterministic-replay",
|
|
51
|
+
"tamper-detected",
|
|
52
|
+
"stale-input-detected",
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
export const READINESS_STAGE_IDS = readinessStageIdSchema.options;
|
|
56
|
+
export const readinessJourneyFindings = (input, evidenceIds) => [
|
|
57
|
+
...identityFindings(input),
|
|
58
|
+
...fixtureFindings(input),
|
|
59
|
+
...stageFindings(input, evidenceIds),
|
|
60
|
+
...capabilityFindings(input),
|
|
61
|
+
...workflowFindings(input),
|
|
62
|
+
...authorityFindings(input),
|
|
63
|
+
...outcomeFindings(input, evidenceIds),
|
|
64
|
+
];
|
|
65
|
+
const identityFindings = (input) => {
|
|
66
|
+
const findings = [];
|
|
67
|
+
if (!input.identity.versions.some(({ state }) => state === "stale"))
|
|
68
|
+
findings.push(finding("version-skew-observation-missing", "diagnose-environment", "fail", "The journey did not preserve a stale version observation."));
|
|
69
|
+
if (!input.identity.versions.some(({ state }) => state === "current"))
|
|
70
|
+
findings.push(finding("corrected-version-observation-missing", "diagnose-environment", "fail", "The journey did not preserve corrected current version state."));
|
|
71
|
+
if (!input.identity.providers.some(({ state }) => state === "broken-host"))
|
|
72
|
+
findings.push(finding("broken-host-observation-missing", "diagnose-environment", "fail", "The journey did not distinguish a broken host dependency."));
|
|
73
|
+
return findings;
|
|
74
|
+
};
|
|
75
|
+
const fixtureFindings = (input) => {
|
|
76
|
+
const requiredKinds = [
|
|
77
|
+
"native",
|
|
78
|
+
"javascript-cli",
|
|
79
|
+
"electron",
|
|
80
|
+
"incomplete-reconstruction",
|
|
81
|
+
"broken-runtime",
|
|
82
|
+
];
|
|
83
|
+
return requiredKinds.flatMap((kind) => input.fixtures.some(({ kind: fixtureKind }) => fixtureKind === kind)
|
|
84
|
+
? []
|
|
85
|
+
: [
|
|
86
|
+
finding("representative-fixture-missing", "discover-classify", "fail", `The required ${kind} fixture is missing.`),
|
|
87
|
+
]);
|
|
88
|
+
};
|
|
89
|
+
const stageFindings = (input, evidenceIds) => {
|
|
90
|
+
const findings = [];
|
|
91
|
+
for (const stageId of READINESS_STAGE_IDS) {
|
|
92
|
+
const matching = input.stages.filter(({ stage_id: id }) => id === stageId);
|
|
93
|
+
if (matching.length !== 1) {
|
|
94
|
+
findings.push(finding("stage-cardinality", stageId, "fail", `Expected exactly one ${stageId} stage; observed ${String(matching.length)}.`));
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const stage = matching[0];
|
|
98
|
+
if (stage === undefined)
|
|
99
|
+
continue;
|
|
100
|
+
if (!stage.required)
|
|
101
|
+
findings.push(finding("required-stage-disabled", stageId, "fail", "The public conformance journey requires this stage."));
|
|
102
|
+
const checks = new Map(stage.checks.map((check) => [check.check_id, check]));
|
|
103
|
+
if (checks.size !== stage.checks.length)
|
|
104
|
+
findings.push(finding("duplicate-stage-check", stageId, "fail", "Stage check IDs must be unique."));
|
|
105
|
+
for (const checkId of READINESS_REQUIRED_CHECKS[stageId]) {
|
|
106
|
+
const check = checks.get(checkId);
|
|
107
|
+
if (check === undefined) {
|
|
108
|
+
findings.push(finding("missing-stage-check", stageId, "fail", `Required conformance check is missing: ${checkId}.`));
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (check.status !== "pass")
|
|
112
|
+
findings.push(finding("stage-check-not-pass", stageId, check.status === "fail" ? "fail" : "unknown", `${checkId} is ${check.status}: ${check.detail}`, check.evidence_ids));
|
|
113
|
+
if (check.evidence_ids.length === 0)
|
|
114
|
+
findings.push(finding("stage-check-evidence-missing", stageId, "unknown", `${checkId} has no attributable Evidence.`));
|
|
115
|
+
addMissingEvidenceFindings(findings, stageId, [...stage.evidence_ids, ...check.evidence_ids], evidenceIds);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return findings;
|
|
119
|
+
};
|
|
120
|
+
const capabilityFindings = (input) => input.capabilities.flatMap((capability) => {
|
|
121
|
+
const findings = [];
|
|
122
|
+
if (capability.bounded && capability.limits.length === 0)
|
|
123
|
+
findings.push(finding("bounded-limit-hidden", "discover-classify", "fail", `${capability.capability_id} is bounded but declares no exact limits.`));
|
|
124
|
+
if (!capability.available && capability.unavailable_reason === null)
|
|
125
|
+
findings.push(finding("unavailable-reason-missing", "discover-classify", "unknown", `${capability.capability_id} is unavailable without an actionable reason.`));
|
|
126
|
+
return findings;
|
|
127
|
+
});
|
|
128
|
+
const workflowFindings = (input) => {
|
|
129
|
+
const findings = [];
|
|
130
|
+
for (const fixture of input.fixtures) {
|
|
131
|
+
const selected = input.workflow_candidates.filter(({ fixture_id: fixtureId, selected: isSelected }) => fixtureId === fixture.fixture_id && isSelected);
|
|
132
|
+
if (selected.length !== 1 || selected[0]?.compatibility !== "compatible")
|
|
133
|
+
findings.push(finding("compatible-workflow-not-selected", "discover-classify", "fail", `${fixture.fixture_id} does not have exactly one compatible selected workflow.`));
|
|
134
|
+
}
|
|
135
|
+
for (const candidate of input.workflow_candidates)
|
|
136
|
+
if (candidate.invoked && candidate.compatibility !== "compatible")
|
|
137
|
+
findings.push(finding("incompatible-provider-invoked", "static-analysis", "fail", `${candidate.workflow_id} was invoked despite ${candidate.compatibility} routing.`));
|
|
138
|
+
return findings;
|
|
139
|
+
};
|
|
140
|
+
const authorityFindings = (input) => {
|
|
141
|
+
const deniedScopes = new Set(input.grants
|
|
142
|
+
.filter(({ decision }) => ["denied", "cancelled"].includes(decision))
|
|
143
|
+
.map(({ scope }) => scope));
|
|
144
|
+
const recoveredScopes = new Set(input.grants
|
|
145
|
+
.filter(({ decision }) => decision === "granted")
|
|
146
|
+
.map(({ scope }) => scope));
|
|
147
|
+
return [...deniedScopes].some((scope) => recoveredScopes.has(scope))
|
|
148
|
+
? []
|
|
149
|
+
: [
|
|
150
|
+
finding("narrow-authority-recovery-missing", "acquire-authority", "fail", "No denied or cancelled scope was later recovered by a narrow grant."),
|
|
151
|
+
];
|
|
152
|
+
};
|
|
153
|
+
const outcomeFindings = (input, evidenceIds) => {
|
|
154
|
+
const findings = [];
|
|
155
|
+
const parity = new Map();
|
|
156
|
+
for (const outcome of input.operation_outcomes) {
|
|
157
|
+
const expectedCliExit = outcome.expected_success ? 0 : 1;
|
|
158
|
+
if (outcome.surface === "cli" &&
|
|
159
|
+
(outcome.cli_exit_code === null ||
|
|
160
|
+
(expectedCliExit === 0
|
|
161
|
+
? outcome.cli_exit_code !== 0
|
|
162
|
+
: outcome.cli_exit_code === 0)))
|
|
163
|
+
findings.push(finding("cli-status-mismatch", "export-replay", "fail", `${outcome.operation} CLI process status contradicts its structured outcome.`, outcome.evidence_ids));
|
|
164
|
+
if (outcome.surface === "mcp" &&
|
|
165
|
+
outcome.mcp_status !==
|
|
166
|
+
(outcome.expected_success ? "success" : "non-success"))
|
|
167
|
+
findings.push(finding("mcp-status-mismatch", "export-replay", "fail", `${outcome.operation} MCP status contradicts its structured outcome.`, outcome.evidence_ids));
|
|
168
|
+
const key = `${outcome.operation}:${outcome.call_kind}:${String(outcome.expected_success)}`;
|
|
169
|
+
parity.set(key, new Set([...(parity.get(key) ?? []), outcome.surface]));
|
|
170
|
+
addMissingEvidenceFindings(findings, "export-replay", outcome.evidence_ids, evidenceIds);
|
|
171
|
+
}
|
|
172
|
+
for (const [key, surfaces] of parity)
|
|
173
|
+
if (surfaces.size !== 2)
|
|
174
|
+
findings.push(finding("surface-parity-missing", "export-replay", "fail", `CLI/MCP outcome pair is incomplete: ${key}.`));
|
|
175
|
+
for (const [key, outcomes] of groupedOutcomes(input)) {
|
|
176
|
+
const cli = outcomes.find(({ surface }) => surface === "cli");
|
|
177
|
+
const mcp = outcomes.find(({ surface }) => surface === "mcp");
|
|
178
|
+
if (cli !== undefined &&
|
|
179
|
+
mcp !== undefined &&
|
|
180
|
+
(cli.expected_success !== mcp.expected_success ||
|
|
181
|
+
cli.error_code !== mcp.error_code))
|
|
182
|
+
findings.push(finding("surface-semantic-drift", "export-replay", "fail", `CLI/MCP structured outcomes disagree: ${key}.`, [...cli.evidence_ids, ...mcp.evidence_ids]));
|
|
183
|
+
}
|
|
184
|
+
return findings;
|
|
185
|
+
};
|
|
186
|
+
const groupedOutcomes = (input) => {
|
|
187
|
+
const grouped = new Map();
|
|
188
|
+
for (const outcome of input.operation_outcomes) {
|
|
189
|
+
const key = `${outcome.operation}:${outcome.call_kind}`;
|
|
190
|
+
grouped.set(key, [...(grouped.get(key) ?? []), outcome]);
|
|
191
|
+
}
|
|
192
|
+
return grouped;
|
|
193
|
+
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { evidenceBundleSchema } from "./evidenceBundle.js";
|
|
3
|
+
import { reconstructionObligationLedgerSchema } from "./reconstructionObligationLedgerSchemas.js";
|
|
4
|
+
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
5
|
+
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
|
|
6
|
+
const stableIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._:/-]{0,199}$/u);
|
|
7
|
+
const boundedTextSchema = z.string().trim().min(1).max(4_096);
|
|
8
|
+
export const readinessStatusSchema = z.enum([
|
|
9
|
+
"pass",
|
|
10
|
+
"fail",
|
|
11
|
+
"unknown",
|
|
12
|
+
"unsupported",
|
|
13
|
+
"truncated",
|
|
14
|
+
"skipped",
|
|
15
|
+
]);
|
|
16
|
+
export const readinessStageIdSchema = z.enum([
|
|
17
|
+
"discover-classify",
|
|
18
|
+
"diagnose-environment",
|
|
19
|
+
"acquire-authority",
|
|
20
|
+
"static-analysis",
|
|
21
|
+
"reactive-scenarios",
|
|
22
|
+
"compare-authority-candidate",
|
|
23
|
+
"preserve-contradictions",
|
|
24
|
+
"verify-reconstruction-closure",
|
|
25
|
+
"export-replay",
|
|
26
|
+
]);
|
|
27
|
+
const versionObservationSchema = z.strictObject({
|
|
28
|
+
component: stableIdSchema,
|
|
29
|
+
version: boundedTextSchema.nullable(),
|
|
30
|
+
digest: digestSchema.nullable(),
|
|
31
|
+
state: z.enum(["current", "stale", "unavailable"]),
|
|
32
|
+
remediation: boundedTextSchema.nullable(),
|
|
33
|
+
});
|
|
34
|
+
const providerIdentitySchema = z.strictObject({
|
|
35
|
+
provider_id: stableIdSchema,
|
|
36
|
+
version: boundedTextSchema.nullable(),
|
|
37
|
+
digest: digestSchema.nullable(),
|
|
38
|
+
state: z.enum(["available", "unavailable", "incompatible", "broken-host"]),
|
|
39
|
+
reason_code: stableIdSchema.nullable(),
|
|
40
|
+
});
|
|
41
|
+
const limitSchema = z.strictObject({
|
|
42
|
+
name: stableIdSchema,
|
|
43
|
+
value: z.number().finite().nonnegative(),
|
|
44
|
+
unit: z.enum(["count", "bytes", "milliseconds", "ratio"]),
|
|
45
|
+
});
|
|
46
|
+
const capabilitySchema = z.strictObject({
|
|
47
|
+
capability_id: stableIdSchema,
|
|
48
|
+
available: z.boolean(),
|
|
49
|
+
bounded: z.boolean(),
|
|
50
|
+
side_effect: z.enum([
|
|
51
|
+
"none",
|
|
52
|
+
"reads-target",
|
|
53
|
+
"launches-process",
|
|
54
|
+
"writes-workspace",
|
|
55
|
+
"network-observation",
|
|
56
|
+
]),
|
|
57
|
+
authority_scopes: z.array(stableIdSchema).max(100),
|
|
58
|
+
limits: z.array(limitSchema).max(100),
|
|
59
|
+
unavailable_reason: boundedTextSchema.nullable(),
|
|
60
|
+
});
|
|
61
|
+
const fixtureSchema = z.strictObject({
|
|
62
|
+
fixture_id: stableIdSchema,
|
|
63
|
+
kind: z.enum([
|
|
64
|
+
"native",
|
|
65
|
+
"javascript-cli",
|
|
66
|
+
"electron",
|
|
67
|
+
"incomplete-reconstruction",
|
|
68
|
+
"broken-runtime",
|
|
69
|
+
]),
|
|
70
|
+
artifact_sha256: digestSchema,
|
|
71
|
+
environment_id: stableIdSchema,
|
|
72
|
+
deliberate_faults: z.array(stableIdSchema).min(1).max(100),
|
|
73
|
+
});
|
|
74
|
+
const workflowCandidateSchema = z.strictObject({
|
|
75
|
+
fixture_id: stableIdSchema,
|
|
76
|
+
workflow_id: stableIdSchema,
|
|
77
|
+
provider_id: stableIdSchema.nullable(),
|
|
78
|
+
selected: z.boolean(),
|
|
79
|
+
invoked: z.boolean(),
|
|
80
|
+
compatibility: z.enum(["compatible", "incompatible", "unavailable"]),
|
|
81
|
+
reason_code: stableIdSchema,
|
|
82
|
+
});
|
|
83
|
+
const grantSchema = z.strictObject({
|
|
84
|
+
grant_id: stableIdSchema,
|
|
85
|
+
scope: stableIdSchema,
|
|
86
|
+
decision: z.enum(["granted", "denied", "cancelled", "restart-required"]),
|
|
87
|
+
launched_process: z.boolean(),
|
|
88
|
+
evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
89
|
+
});
|
|
90
|
+
const comparisonSchema = z.strictObject({
|
|
91
|
+
comparison_id: stableIdSchema,
|
|
92
|
+
verdict: z.enum(["equivalent", "different", "unknown"]),
|
|
93
|
+
schedule_semantics: z.enum(["total-order", "partial-order", "finite-traces"]),
|
|
94
|
+
concurrent: z.boolean(),
|
|
95
|
+
truncated: z.boolean(),
|
|
96
|
+
unavailable_authority: z.boolean(),
|
|
97
|
+
unstable: z.boolean(),
|
|
98
|
+
deliberate_divergence_ref: boundedTextSchema.nullable(),
|
|
99
|
+
divergence_refs: z.array(boundedTextSchema).max(100),
|
|
100
|
+
contradiction_ids: z.array(stableIdSchema).max(100),
|
|
101
|
+
evidence_ids: z.array(evidenceIdSchema).min(1).max(1_000),
|
|
102
|
+
});
|
|
103
|
+
const contradictionSchema = z.strictObject({
|
|
104
|
+
contradiction_id: stableIdSchema,
|
|
105
|
+
declared_sha256: digestSchema,
|
|
106
|
+
observed_sha256: digestSchema,
|
|
107
|
+
policy: z.literal("record-and-continue"),
|
|
108
|
+
affected_comparison_ids: z.array(stableIdSchema).min(1).max(100),
|
|
109
|
+
evidence_ids: z.array(evidenceIdSchema).min(2).max(100),
|
|
110
|
+
});
|
|
111
|
+
const operationOutcomeSchema = z.strictObject({
|
|
112
|
+
sequence: z.number().int().min(0),
|
|
113
|
+
operation: stableIdSchema,
|
|
114
|
+
surface: z.enum(["cli", "mcp"]),
|
|
115
|
+
call_kind: z.enum([
|
|
116
|
+
"valid",
|
|
117
|
+
"malformed",
|
|
118
|
+
"over-limit",
|
|
119
|
+
"incompatible-provider",
|
|
120
|
+
"setup",
|
|
121
|
+
"permission",
|
|
122
|
+
"operation",
|
|
123
|
+
]),
|
|
124
|
+
expected_success: z.boolean(),
|
|
125
|
+
cli_exit_code: z.number().int().min(0).nullable(),
|
|
126
|
+
mcp_status: z.enum(["success", "non-success"]).nullable(),
|
|
127
|
+
error_code: stableIdSchema.nullable(),
|
|
128
|
+
recovered: z.boolean(),
|
|
129
|
+
evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
130
|
+
});
|
|
131
|
+
const cleanupSchema = z.strictObject({
|
|
132
|
+
run_id: stableIdSchema,
|
|
133
|
+
cancelled: z.boolean(),
|
|
134
|
+
owned_resources_remaining: z.number().int().min(0),
|
|
135
|
+
diagnostic_evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
136
|
+
});
|
|
137
|
+
const closureObservationSchema = z.strictObject({
|
|
138
|
+
sequence: z.number().int().min(0),
|
|
139
|
+
ledger_digest: digestSchema,
|
|
140
|
+
status: z.enum(["ready", "open", "failed", "unknown"]),
|
|
141
|
+
required_open: z.number().int().min(0),
|
|
142
|
+
newly_verified_obligation_ids: z.array(stableIdSchema).max(10_000),
|
|
143
|
+
evidence_ids: z.array(evidenceIdSchema).min(1).max(1_000),
|
|
144
|
+
});
|
|
145
|
+
const delegationCheckSchema = z.strictObject({
|
|
146
|
+
candidate_id: stableIdSchema,
|
|
147
|
+
delegates_to_authority: z.boolean(),
|
|
148
|
+
evidence_ids: z.array(evidenceIdSchema).min(1).max(100),
|
|
149
|
+
});
|
|
150
|
+
const stageCheckSchema = z.strictObject({
|
|
151
|
+
check_id: stableIdSchema,
|
|
152
|
+
status: readinessStatusSchema,
|
|
153
|
+
detail: boundedTextSchema,
|
|
154
|
+
evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
155
|
+
});
|
|
156
|
+
const stageSchema = z.strictObject({
|
|
157
|
+
stage_id: readinessStageIdSchema,
|
|
158
|
+
required: z.boolean(),
|
|
159
|
+
status: readinessStatusSchema,
|
|
160
|
+
capability_issue: stableIdSchema.nullable(),
|
|
161
|
+
next_action: boundedTextSchema.nullable(),
|
|
162
|
+
evidence_ids: z.array(evidenceIdSchema).max(1_000),
|
|
163
|
+
checks: z.array(stageCheckSchema).max(100),
|
|
164
|
+
});
|
|
165
|
+
const replaySchema = z.strictObject({
|
|
166
|
+
expected_source_digest: digestSchema.nullable(),
|
|
167
|
+
deterministic: z.boolean(),
|
|
168
|
+
tamper_detected: z.boolean(),
|
|
169
|
+
stale_input_detected: z.boolean(),
|
|
170
|
+
evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
171
|
+
});
|
|
172
|
+
export const reconstructionReadinessInputSchema = z.strictObject({
|
|
173
|
+
schema_version: z.literal(1),
|
|
174
|
+
identity: z.strictObject({
|
|
175
|
+
cli_version: boundedTextSchema,
|
|
176
|
+
server_version: boundedTextSchema,
|
|
177
|
+
catalog_digest: digestSchema,
|
|
178
|
+
skill_digest: digestSchema.nullable(),
|
|
179
|
+
versions: z.array(versionObservationSchema).min(1).max(100),
|
|
180
|
+
providers: z.array(providerIdentitySchema).max(100),
|
|
181
|
+
}),
|
|
182
|
+
client: z.strictObject({
|
|
183
|
+
name: boundedTextSchema,
|
|
184
|
+
version: boundedTextSchema,
|
|
185
|
+
negotiated_capabilities: z.array(stableIdSchema).max(100),
|
|
186
|
+
}),
|
|
187
|
+
capabilities: z.array(capabilitySchema).min(1).max(1_000),
|
|
188
|
+
fixtures: z.array(fixtureSchema).min(1).max(100),
|
|
189
|
+
workflow_candidates: z.array(workflowCandidateSchema).min(1).max(1_000),
|
|
190
|
+
grants: z.array(grantSchema).max(1_000),
|
|
191
|
+
evidence_bundle: evidenceBundleSchema,
|
|
192
|
+
comparisons: z.array(comparisonSchema).max(1_000),
|
|
193
|
+
contradictions: z.array(contradictionSchema).max(1_000),
|
|
194
|
+
obligation_ledger: reconstructionObligationLedgerSchema,
|
|
195
|
+
operation_outcomes: z.array(operationOutcomeSchema).max(10_000),
|
|
196
|
+
cleanup: z.array(cleanupSchema).max(1_000),
|
|
197
|
+
closure_history: z.array(closureObservationSchema).min(2).max(1_000),
|
|
198
|
+
delegation_checks: z.array(delegationCheckSchema).min(1).max(1_000),
|
|
199
|
+
replay: replaySchema,
|
|
200
|
+
stages: z.array(stageSchema).max(20),
|
|
201
|
+
});
|
|
202
|
+
const findingSchema = z.strictObject({
|
|
203
|
+
code: stableIdSchema,
|
|
204
|
+
stage_id: readinessStageIdSchema,
|
|
205
|
+
status: z.enum(["fail", "unknown"]),
|
|
206
|
+
detail: boundedTextSchema,
|
|
207
|
+
evidence_ids: z.array(evidenceIdSchema).max(100),
|
|
208
|
+
});
|
|
209
|
+
export const reconstructionReadinessReportSchema = z.strictObject({
|
|
210
|
+
schema: z.literal("ReconstructionReadinessReport"),
|
|
211
|
+
schema_version: z.literal(1),
|
|
212
|
+
report_id: z.string().regex(/^rr_[a-f0-9]{64}$/u),
|
|
213
|
+
source_digest: digestSchema,
|
|
214
|
+
report_digest: digestSchema,
|
|
215
|
+
status: readinessStatusSchema,
|
|
216
|
+
summary: z.strictObject({
|
|
217
|
+
stages: z.number().int().min(0),
|
|
218
|
+
required_stages: z.number().int().min(0),
|
|
219
|
+
passed_required_stages: z.number().int().min(0),
|
|
220
|
+
findings: z.number().int().min(0),
|
|
221
|
+
failed_findings: z.number().int().min(0),
|
|
222
|
+
unknown_findings: z.number().int().min(0),
|
|
223
|
+
}),
|
|
224
|
+
metrics: z.strictObject({
|
|
225
|
+
first_valid_workflow_selection_rate: z.number().min(0).max(1),
|
|
226
|
+
malformed_or_over_limit_call_rate: z.number().min(0).max(1),
|
|
227
|
+
incompatible_provider_invocations: z.number().int().min(0),
|
|
228
|
+
failed_calls_before_prerequisites: z.number().int().min(0),
|
|
229
|
+
recovery_rate: z.number().min(0).max(1),
|
|
230
|
+
divergence_localization_precision: z.number().min(0).max(1),
|
|
231
|
+
false_equivalence_count: z.number().int().min(0),
|
|
232
|
+
unowned_obligation_count: z.number().int().min(0),
|
|
233
|
+
cleanup_leak_count: z.number().int().min(0),
|
|
234
|
+
nondeterministic_replay_count: z.number().int().min(0),
|
|
235
|
+
}),
|
|
236
|
+
stages: z.array(stageSchema).max(20),
|
|
237
|
+
findings: z.array(findingSchema).max(10_000),
|
|
238
|
+
evidence_links: z.array(evidenceIdSchema).max(100_000),
|
|
239
|
+
snapshot: reconstructionReadinessInputSchema,
|
|
240
|
+
});
|