rea-agents 2.5.0 → 3.1.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 +20 -12
- package/bridge/ghidra/ReaGhidraBridge.java +477 -4
- package/bridge/hopper_bridge.py +54 -4
- package/dist/application/AnalysisContextQueries.js +142 -0
- package/dist/application/AnalysisSnapshotCache.js +4 -2
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
- package/dist/application/ArtifactInventory/policy.js +17 -0
- package/dist/application/ArtifactInventory/reader.js +1 -4
- package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
- package/dist/application/ArtifactInventory/scanReader.js +7 -7
- package/dist/application/ArtifactInventory/types.js +1 -5
- package/dist/application/BinarySession.js +19 -20
- package/dist/application/BinarySessionComposition.js +21 -0
- package/dist/application/BinarySessionRecords.js +106 -10
- package/dist/application/BinarySessionStatus.js +11 -5
- package/dist/application/BrowserEvidence.js +3 -5
- package/dist/application/CapabilityClientRequirements.js +26 -0
- package/dist/application/CapabilityInventory.js +140 -55
- package/dist/application/ClientRegistrationStatus.js +4 -1
- package/dist/application/CrossVersionInventory.js +7 -6
- package/dist/application/DirectAnalysis.js +6 -2
- package/dist/application/ElectronActiveEvidence.js +55 -0
- package/dist/application/ElectronActiveObservationPort.js +1 -0
- package/dist/application/ElectronActiveObservationService.js +81 -0
- package/dist/application/EnhancedTools.js +49 -17
- package/dist/application/EvidenceBundleCommands.js +5 -1
- package/dist/application/EvidenceLedger.js +53 -17
- package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
- package/dist/application/JavaScriptReplayPermission.js +1 -1
- package/dist/application/JavaScriptReplayService.js +23 -15
- package/dist/application/LazyAnalysisProvider.js +77 -0
- package/dist/application/LoopbackReplay.js +1 -1
- package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
- package/dist/application/NativeApiInspection.js +80 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
- package/dist/application/ProcessCaptureLifecycle.js +5 -0
- package/dist/application/ProcessCli.js +2 -1
- package/dist/application/ProcessHarness.js +8 -3
- package/dist/application/ProcessNormalization.js +2 -1
- package/dist/application/ProjectPermissionStore.js +1 -0
- package/dist/application/ReferenceSourceImport.js +2 -2
- package/dist/application/SessionProviderRouter.js +6 -6
- package/dist/application/SetupClientConfiguration.js +10 -3
- package/dist/application/WindowsCapabilities.js +5 -4
- package/dist/application/runtime.js +26 -9
- package/dist/artifacts/ArtifactProvider.js +8 -10
- package/dist/artifacts/SafeOutputTree.js +7 -8
- package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
- package/dist/browser/CdpElectronInspection.js +3 -1
- package/dist/browser/JavaScriptRuntimeScope.js +5 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +8 -2
- package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
- package/dist/browser/PlaywrightScenarioSession.js +4 -4
- package/dist/browser/SensitiveTextCapture.js +1 -1
- package/dist/browser/V8InspectorCaptureProjection.js +1 -0
- package/dist/browser/V8InspectorProvider.js +3 -3
- package/dist/catalogIdentity.js +15 -9
- package/dist/cli/artifactCommands.js +5 -3
- package/dist/cli/coreAnalysisCommands.js +41 -0
- package/dist/cli/managedCommands.js +1 -1
- package/dist/cliApplicationCommands.js +2 -2
- package/dist/cliBrowserAdvancedCommands.js +11 -5
- package/dist/cliBrowserCommands.js +14 -7
- package/dist/cliCommandNames.js +2 -0
- package/dist/cliElectronCommands.js +46 -4
- package/dist/cliJavaScriptRuntimeCommands.js +14 -6
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliPolicyCommands.js +1 -0
- package/dist/config/browserScenario.js +77 -0
- package/dist/config/electronAutomation.js +35 -0
- package/dist/config/environment.js +6 -0
- package/dist/config/javascriptReplay.js +41 -0
- package/dist/config/managedRuntime.js +25 -0
- package/dist/config/parseConfig.js +56 -200
- package/dist/config/parsers.js +10 -1
- package/dist/config/passiveObservation.js +157 -0
- package/dist/config/processCapture.js +47 -0
- package/dist/contracts/applicationToolContracts.js +2 -5
- package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
- package/dist/contracts/artifactToolContracts.js +35 -37
- package/dist/contracts/browserToolContracts.js +2 -2
- package/dist/contracts/electronToolContracts.js +30 -1
- package/dist/contracts/enhancedInputs.js +21 -27
- package/dist/contracts/functionWorkflowToolContracts.js +29 -0
- package/dist/contracts/managedToolContracts.js +4 -9
- package/dist/contracts/managedWorkflowExamples.js +12 -9
- package/dist/contracts/managedWorkflowToolContracts.js +30 -27
- package/dist/contracts/nativeToolContracts.js +2 -3
- package/dist/contracts/promptContracts.js +14 -15
- package/dist/contracts/sessionToolSchemas.js +61 -0
- package/dist/contracts/toolContractExamples.js +4 -0
- package/dist/contracts/toolContractHelpers.js +23 -0
- package/dist/contracts/toolContracts.js +12 -67
- package/dist/contracts/toolEffects.js +19 -0
- package/dist/contracts/toolOutputSchemaGroups.js +66 -11
- package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
- package/dist/contracts/toolSchemaMetadata.js +128 -0
- package/dist/doctorRuntime.js +1 -1
- package/dist/domain/analysisErrorPresentation.js +8 -2
- package/dist/domain/analysisErrorProjection.js +1 -0
- package/dist/domain/androidApplication.js +2 -0
- package/dist/domain/appleApplication.js +2 -0
- package/dist/domain/binaryTarget.js +7 -5
- package/dist/domain/binaryTargetTypes.js +1 -0
- package/dist/domain/browserCaptureComparison.js +21 -69
- package/dist/domain/browserObservation.js +22 -9
- package/dist/domain/bytecodeProvider.js +177 -0
- package/dist/domain/callPath.js +3 -2
- package/dist/domain/conformancePackage.js +169 -0
- package/dist/domain/conformanceReplay.js +104 -0
- package/dist/domain/conformanceTrustGate.js +328 -0
- package/dist/domain/customProtocolCapture.js +137 -0
- package/dist/domain/electronActiveObservation.js +277 -0
- package/dist/domain/electronObservation.js +15 -11
- package/dist/domain/electronStaticAnalysisValues.js +4 -1
- package/dist/domain/eventProcessTree.js +217 -0
- package/dist/domain/evidenceBundle.js +47 -0
- package/dist/domain/functionComparisonNormalization.js +15 -8
- package/dist/domain/functionDossierEvidence.js +9 -4
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +68 -68
- package/dist/domain/inputIssueProjection.js +11 -2
- package/dist/domain/investigationWorkspace.js +16 -15
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
- package/dist/domain/javascriptReplay.js +79 -63
- package/dist/domain/javascriptRuntimeObservation.js +1 -0
- package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
- package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
- package/dist/domain/javascriptSemanticAnalysis.js +8 -12
- package/dist/domain/javascriptSourceParser.js +15 -0
- package/dist/domain/javascriptStaticAnalysis.js +8 -12
- package/dist/domain/knownPageCoverage.js +15 -7
- package/dist/domain/mobileApplicationInvestigation.js +159 -0
- package/dist/domain/nativeApiBoundary.js +138 -0
- package/dist/domain/nodeRuntimeCharacterization.js +14 -13
- package/dist/domain/objcSwiftMetadata.js +150 -0
- package/dist/domain/packageAnalysis.js +123 -0
- package/dist/domain/peInspection.js +196 -0
- package/dist/domain/processCaptureReactiveValidation.js +8 -3
- package/dist/domain/processCaptureValidation.js +7 -3
- package/dist/domain/processComparison.js +12 -7
- package/dist/domain/processObservation.js +5 -6
- package/dist/domain/processReactiveMatching.js +14 -7
- package/dist/domain/processReactiveTransition.js +9 -3
- package/dist/domain/processScenario.js +6 -3
- package/dist/domain/processTraceComparison.js +3 -2
- package/dist/domain/protocolCapture.js +245 -0
- package/dist/domain/reconstructionReadinessSchemas.js +30 -2
- package/dist/domain/referenceSourceImportParsing.js +2 -2
- package/dist/domain/replayMachineRuntime.js +5 -3
- package/dist/domain/sourceToBundleComparison.js +2 -2
- package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
- package/dist/domain/sourceToBundleSignals.js +7 -1
- package/dist/domain/staticRuntimeCorrelation.js +7 -5
- package/dist/domain/webBundleAnalysis.js +14 -14
- package/dist/domain/webCaptureDiff.js +15 -12
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
- package/dist/dotnet/ManagedStaticProvider.js +34 -5
- package/dist/generatedMcpToolCatalog.js +37 -0
- package/dist/generatedPackageMetadata.js +4 -4
- package/dist/ghidra/GhidraClient.js +1 -1
- package/dist/ghidra/GhidraClientStartup.js +1 -1
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraFunctionValues.js +44 -16
- package/dist/ghidra/GhidraInventoryValues.js +57 -47
- package/dist/ghidra/GhidraProvider.js +18 -10
- package/dist/ghidra/GhidraProviderCapabilities.js +45 -39
- package/dist/ghidra/GhidraSocketConnection.js +1 -1
- package/dist/ghidra/protocol.js +19 -42
- package/dist/hopper/BridgeLauncher.js +3 -1
- package/dist/hopper/HopperAnalysisProfile.js +2 -4
- package/dist/hopper/HopperCleanup.js +5 -6
- package/dist/hopper/HopperClient.js +27 -3
- package/dist/hopper/HopperProvider.js +42 -44
- package/dist/hopper/HopperRequestQueue.js +32 -4
- package/dist/hopper/HopperResponseStream.js +2 -2
- package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
- package/dist/hopper/protocol.js +63 -21
- package/dist/main/reload.js +1 -6
- package/dist/main/state.js +0 -14
- package/dist/main/transport.js +31 -41
- package/dist/main.js +17 -13
- package/dist/mcpDoctor.js +4 -26
- package/dist/mcpStartupPolicy.js +14 -0
- package/dist/process/PrivateRuntimeRoot.js +17 -0
- package/dist/process/ProcessOwnership.js +64 -128
- package/dist/process/ProcessOwnershipIdentity.js +13 -0
- package/dist/process/ProcessOwnershipObservation.js +88 -0
- package/dist/process/ProcessOwnershipProcessTree.js +22 -0
- package/dist/process/ProviderDeadline.js +8 -12
- package/dist/process/WindowsAuthority.js +32 -0
- package/dist/reference/ReferenceSourceReader.js +3 -3
- package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
- package/dist/replay/JavaScriptReplayWorker.js +95 -11
- package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
- package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
- package/dist/replay/ReplayOutcome.js +26 -15
- package/dist/replay/ReplayWorkerProtocol.js +34 -29
- package/dist/server/createServer.js +101 -144
- package/dist/server/mcpClientMetadata.js +32 -0
- package/dist/server/registerApplicationTools/characterization.js +6 -13
- package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
- package/dist/server/registerApplicationTools/compareVersions.js +3 -8
- package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
- package/dist/server/registerApplicationTools/coverage.js +13 -19
- package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
- package/dist/server/registerApplicationTools/readiness.js +1 -6
- package/dist/server/registerApplicationTools/traceFeature.js +3 -8
- package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
- package/dist/server/registerArtifactComparisonTool.js +12 -16
- package/dist/server/registerBrowserScenarioTool.js +1 -6
- package/dist/server/registerBrowserTools.js +37 -79
- package/dist/server/registerBundleComparisonTool.js +10 -14
- package/dist/server/registerCloseLifecycleTool.js +6 -14
- package/dist/server/registerElectronTools.js +30 -47
- package/dist/server/registerEnhancedTools.js +124 -122
- package/dist/server/registerEvidenceResources.js +50 -101
- package/dist/server/registerEvidenceTools.js +5 -9
- package/dist/server/registerFunctionComparisonTool.js +11 -15
- package/dist/server/registerInvestigationTools.js +42 -59
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
- package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
- package/dist/server/registerOfficialTools.js +8 -9
- package/dist/server/registerProcessComparisonTool.js +19 -24
- package/dist/server/registerReconstructionObligationLedgerResource.js +0 -7
- package/dist/server/registerReconstructionReadinessResource.js +0 -7
- package/dist/server/registerReplayMachineTool.js +4 -10
- package/dist/server/registerSessionRecordTools.js +146 -47
- package/dist/server/registerSessionStatusTool.js +14 -29
- package/dist/server/registerSessionTools.js +45 -41
- package/dist/server/sessionAvailabilityPolicy.js +2 -1
- package/dist/server/sessionToolPolicies.js +1 -5
- package/dist/server/toolRegistrationOptions.js +4 -177
- package/dist/server/toolResult.js +14 -18
- package/package.json +35 -16
- package/scripts/electron-active-hook-boundaries.cjs +394 -0
- package/scripts/electron-active-hook.cjs +501 -0
- package/skills/reverse-engineer-anything/SKILL.md +10 -3
- package/dist/server/DynamicToolAvailability.js +0 -70
- package/dist/server/toolInputValidation.js +0 -77
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Supported managed-runtime bytecode families. */
|
|
3
|
+
export const bytecodeFamilySchema = z.enum(["jvm", "python"]);
|
|
4
|
+
/** Classification of bytecode provenance. */
|
|
5
|
+
export const bytecodeProvenanceSchema = z.enum([
|
|
6
|
+
"application",
|
|
7
|
+
"generated",
|
|
8
|
+
"vendored",
|
|
9
|
+
"bundled",
|
|
10
|
+
"standard_library",
|
|
11
|
+
]);
|
|
12
|
+
/** A bytecode symbol discovered through static analysis. */
|
|
13
|
+
export const bytecodeSymbolSchema = z.strictObject({
|
|
14
|
+
/** Fully qualified name. */
|
|
15
|
+
name: z.string().min(1),
|
|
16
|
+
/** Raw bytecode location or offset. */
|
|
17
|
+
raw_location: z.string().min(1),
|
|
18
|
+
/** Normalized symbol type. */
|
|
19
|
+
kind: z.enum([
|
|
20
|
+
"class",
|
|
21
|
+
"interface",
|
|
22
|
+
"method",
|
|
23
|
+
"field",
|
|
24
|
+
"function",
|
|
25
|
+
"module",
|
|
26
|
+
"variable",
|
|
27
|
+
]),
|
|
28
|
+
/** Bytecode version if known. */
|
|
29
|
+
bytecode_version: z.number().int().nullable(),
|
|
30
|
+
/** Provenance classification. */
|
|
31
|
+
provenance: bytecodeProvenanceSchema,
|
|
32
|
+
/** Whether the symbol is accessible (public). */
|
|
33
|
+
is_public: z.boolean().default(false),
|
|
34
|
+
});
|
|
35
|
+
/** A discovered bytecode artifact (class file, wheel, etc). */
|
|
36
|
+
export const bytecodeArtifactSchema = z.strictObject({
|
|
37
|
+
/** Artifact path relative to the analysis root. */
|
|
38
|
+
path: z.string().min(1),
|
|
39
|
+
/** Bytecode family. */
|
|
40
|
+
family: bytecodeFamilySchema,
|
|
41
|
+
/** Artifact format. */
|
|
42
|
+
format: z.enum(["class", "jar", "war", "ear", "pyc", "pyo", "whl", "zipapp"]),
|
|
43
|
+
/** Size in bytes. */
|
|
44
|
+
size: z.number().int().nonnegative(),
|
|
45
|
+
/** SHA-256 digest. */
|
|
46
|
+
digest: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
47
|
+
/** Discovered symbols. */
|
|
48
|
+
symbols: z.array(bytecodeSymbolSchema).default([]),
|
|
49
|
+
/** Whether this is a standard library artifact. */
|
|
50
|
+
is_standard_library: z.boolean().default(false),
|
|
51
|
+
/** Whether this is a generated artifact. */
|
|
52
|
+
is_generated: z.boolean().default(false),
|
|
53
|
+
/** Whether this is a vendored artifact. */
|
|
54
|
+
is_vendored: z.boolean().default(false),
|
|
55
|
+
});
|
|
56
|
+
/** Static bytecode analysis result. */
|
|
57
|
+
export const bytecodeAnalysisSchema = z.strictObject({
|
|
58
|
+
/** Bytecode family. */
|
|
59
|
+
family: bytecodeFamilySchema,
|
|
60
|
+
/** All discovered artifacts. */
|
|
61
|
+
artifacts: z.array(bytecodeArtifactSchema).min(0).max(10_000),
|
|
62
|
+
/** Total symbols across all artifacts. */
|
|
63
|
+
total_symbols: z.number().int().nonnegative(),
|
|
64
|
+
/** Symbols classified as application code. */
|
|
65
|
+
application_symbols: z.number().int().nonnegative(),
|
|
66
|
+
/** Symbols classified as generated code. */
|
|
67
|
+
generated_symbols: z.number().int().nonnegative(),
|
|
68
|
+
/** Symbols classified as vendored code. */
|
|
69
|
+
vendored_symbols: z.number().int().nonnegative(),
|
|
70
|
+
/** Symbols classified as standard library. */
|
|
71
|
+
standard_library_symbols: z.number().int().nonnegative(),
|
|
72
|
+
});
|
|
73
|
+
/** Detect bytecode family from file extension. */
|
|
74
|
+
export function detectBytecodeFamily(path) {
|
|
75
|
+
const lower = path.toLowerCase();
|
|
76
|
+
if (lower.endsWith(".class") ||
|
|
77
|
+
lower.endsWith(".jar") ||
|
|
78
|
+
lower.endsWith(".war") ||
|
|
79
|
+
lower.endsWith(".ear")) {
|
|
80
|
+
return "jvm";
|
|
81
|
+
}
|
|
82
|
+
if (lower.endsWith(".pyc") ||
|
|
83
|
+
lower.endsWith(".pyo") ||
|
|
84
|
+
lower.endsWith(".whl") ||
|
|
85
|
+
lower.endsWith(".pyz") ||
|
|
86
|
+
lower.endsWith(".zipapp")) {
|
|
87
|
+
return "python";
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/** Detect artifact format from file path. */
|
|
92
|
+
export function detectArtifactFormat(path) {
|
|
93
|
+
const lower = path.toLowerCase();
|
|
94
|
+
if (lower.endsWith(".class"))
|
|
95
|
+
return "class";
|
|
96
|
+
if (lower.endsWith(".jar"))
|
|
97
|
+
return "jar";
|
|
98
|
+
if (lower.endsWith(".war"))
|
|
99
|
+
return "war";
|
|
100
|
+
if (lower.endsWith(".ear"))
|
|
101
|
+
return "ear";
|
|
102
|
+
if (lower.endsWith(".pyc"))
|
|
103
|
+
return "pyc";
|
|
104
|
+
if (lower.endsWith(".pyo"))
|
|
105
|
+
return "pyo";
|
|
106
|
+
if (lower.endsWith(".whl"))
|
|
107
|
+
return "whl";
|
|
108
|
+
if (lower.endsWith(".pyz") || lower.endsWith(".zipapp"))
|
|
109
|
+
return "zipapp";
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const STANDARD_LIBRARY_PATH_MARKERS = [
|
|
113
|
+
"/stdlib/",
|
|
114
|
+
"/site-packages/",
|
|
115
|
+
"java/",
|
|
116
|
+
"javax/",
|
|
117
|
+
"sun/",
|
|
118
|
+
];
|
|
119
|
+
const STANDARD_LIBRARY_SYMBOL_MARKERS = ["java.", "javax.", "sun.", "__"];
|
|
120
|
+
const GENERATED_PATH_MARKERS = [
|
|
121
|
+
"/generated/",
|
|
122
|
+
"_generated",
|
|
123
|
+
"/build/",
|
|
124
|
+
"/target/",
|
|
125
|
+
"/dist-packages/",
|
|
126
|
+
"/__pycache__/",
|
|
127
|
+
];
|
|
128
|
+
const GENERATED_SYMBOL_MARKERS = ["Generated", "_generated"];
|
|
129
|
+
const VENDORED_PATH_MARKERS = [
|
|
130
|
+
"/vendor/",
|
|
131
|
+
"/vendored/",
|
|
132
|
+
"/third_party/",
|
|
133
|
+
"/3rdparty/",
|
|
134
|
+
"/node_modules/",
|
|
135
|
+
];
|
|
136
|
+
const BUNDLED_PATH_MARKERS = ["/bundle/", "/bundled/", ".jar!", ".war!"];
|
|
137
|
+
const includesAny = (value, markers) => markers.some((marker) => value.includes(marker));
|
|
138
|
+
const startsWithAny = (value, markers) => markers.some((marker) => value.startsWith(marker));
|
|
139
|
+
/** Classify bytecode symbol provenance. */
|
|
140
|
+
export function classifyProvenance(path, symbolName) {
|
|
141
|
+
const lower = path.toLowerCase();
|
|
142
|
+
if (includesAny(lower, STANDARD_LIBRARY_PATH_MARKERS) ||
|
|
143
|
+
startsWithAny(symbolName, STANDARD_LIBRARY_SYMBOL_MARKERS))
|
|
144
|
+
return "standard_library";
|
|
145
|
+
if (includesAny(lower, GENERATED_PATH_MARKERS) ||
|
|
146
|
+
includesAny(symbolName, GENERATED_SYMBOL_MARKERS))
|
|
147
|
+
return "generated";
|
|
148
|
+
if (includesAny(lower, VENDORED_PATH_MARKERS))
|
|
149
|
+
return "vendored";
|
|
150
|
+
if (includesAny(lower, BUNDLED_PATH_MARKERS))
|
|
151
|
+
return "bundled";
|
|
152
|
+
return "application";
|
|
153
|
+
}
|
|
154
|
+
/** Analyze a set of bytecode artifacts and produce a summary. */
|
|
155
|
+
export function analyzeBytecodeArtifacts(artifacts, family) {
|
|
156
|
+
const applicationSymbols = artifacts
|
|
157
|
+
.flatMap((a) => a.symbols)
|
|
158
|
+
.filter((s) => s.provenance === "application").length;
|
|
159
|
+
const generatedSymbols = artifacts
|
|
160
|
+
.flatMap((a) => a.symbols)
|
|
161
|
+
.filter((s) => s.provenance === "generated").length;
|
|
162
|
+
const vendoredSymbols = artifacts
|
|
163
|
+
.flatMap((a) => a.symbols)
|
|
164
|
+
.filter((s) => s.provenance === "vendored").length;
|
|
165
|
+
const standardLibrarySymbols = artifacts
|
|
166
|
+
.flatMap((a) => a.symbols)
|
|
167
|
+
.filter((s) => s.provenance === "standard_library").length;
|
|
168
|
+
return {
|
|
169
|
+
family,
|
|
170
|
+
artifacts: artifacts.slice(0, 10_000),
|
|
171
|
+
total_symbols: artifacts.reduce((sum, a) => sum + a.symbols.length, 0),
|
|
172
|
+
application_symbols: applicationSymbols,
|
|
173
|
+
generated_symbols: generatedSymbols,
|
|
174
|
+
vendored_symbols: vendoredSymbols,
|
|
175
|
+
standard_library_symbols: standardLibrarySymbols,
|
|
176
|
+
};
|
|
177
|
+
}
|
package/dist/domain/callPath.js
CHANGED
|
@@ -178,9 +178,10 @@ const parseSnapshots = (groups) => {
|
|
|
178
178
|
return snapshots;
|
|
179
179
|
};
|
|
180
180
|
const assertCompatible = (snapshots) => {
|
|
181
|
-
const
|
|
182
|
-
if (
|
|
181
|
+
const firstEntry = snapshots.values().next();
|
|
182
|
+
if (firstEntry.done)
|
|
183
183
|
return;
|
|
184
|
+
const first = firstEntry.value;
|
|
184
185
|
for (const snapshot of snapshots.values()) {
|
|
185
186
|
if (snapshot.subject.digest.sha256 !== first.subject.digest.sha256 ||
|
|
186
187
|
snapshot.subject.format !== first.subject.format ||
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import canonicalize from "canonicalize";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { evidenceEnvelopeSchema } from "./evidence.js";
|
|
5
|
+
import { evidenceBundleSchema } from "./evidenceBundle.js";
|
|
6
|
+
/** Schema version for the conformance package format. */
|
|
7
|
+
export const CONFORMANCE_PACKAGE_VERSION = 1;
|
|
8
|
+
/** A stable, path-independent identifier for a conformance package. */
|
|
9
|
+
export const conformancePackageIdSchema = z
|
|
10
|
+
.string()
|
|
11
|
+
.regex(/^cp_[a-f0-9]{64}$/u);
|
|
12
|
+
/** Identifier for a single scenario within a package. */
|
|
13
|
+
export const scenarioIdSchema = z
|
|
14
|
+
.string()
|
|
15
|
+
.regex(/^[A-Za-z][A-Za-z0-9._-]{0,99}$/u);
|
|
16
|
+
/** Deterministic manifest for a scenario fixture. */
|
|
17
|
+
export const scenarioManifestSchema = z.strictObject({
|
|
18
|
+
scenario_id: scenarioIdSchema,
|
|
19
|
+
name: z.string().min(1),
|
|
20
|
+
description: z.string().min(1),
|
|
21
|
+
/** Source-owned fixture path relative to the repository root. */
|
|
22
|
+
fixture_path: z.string().min(1),
|
|
23
|
+
/** Expected exit code or null if unspecified. */
|
|
24
|
+
expected_exit_code: z.number().int().nullable(),
|
|
25
|
+
/** Expected output patterns that must appear in the capture. */
|
|
26
|
+
expected_patterns: z.array(z.string()).default([]),
|
|
27
|
+
});
|
|
28
|
+
/** Replay plan describing how a scenario is replayed deterministically. */
|
|
29
|
+
export const replayPlanSchema = z.strictObject({
|
|
30
|
+
scenario_id: scenarioIdSchema,
|
|
31
|
+
/** Ordered steps to execute during replay. */
|
|
32
|
+
steps: z
|
|
33
|
+
.array(z.strictObject({
|
|
34
|
+
step_id: z.string().min(1),
|
|
35
|
+
action: z.string().min(1),
|
|
36
|
+
arguments: z.array(z.string()).default([]),
|
|
37
|
+
timeout_ms: z.number().int().positive(),
|
|
38
|
+
}))
|
|
39
|
+
.min(1)
|
|
40
|
+
.max(100),
|
|
41
|
+
/** Environment variables to set (never inherit host paths). */
|
|
42
|
+
environment: z.record(z.string(), z.string()).default({}),
|
|
43
|
+
});
|
|
44
|
+
/** Shim plan for intercepting observable effects. */
|
|
45
|
+
export const shimPlanSchema = z.strictObject({
|
|
46
|
+
scenario_id: scenarioIdSchema,
|
|
47
|
+
/** Shims to install, each intercepting a named effect. */
|
|
48
|
+
shims: z
|
|
49
|
+
.array(z.strictObject({
|
|
50
|
+
shim_id: z.string().min(1),
|
|
51
|
+
kind: z.enum(["filesystem", "network", "process", "signal"]),
|
|
52
|
+
target: z.string().min(1),
|
|
53
|
+
policy: z.enum(["observe", "allow", "block", "emulate"]),
|
|
54
|
+
}))
|
|
55
|
+
.min(0)
|
|
56
|
+
.max(50),
|
|
57
|
+
});
|
|
58
|
+
/** Expected evidence for a scenario, checked against the captured run. */
|
|
59
|
+
export const expectedEvidenceSchema = z.strictObject({
|
|
60
|
+
scenario_id: scenarioIdSchema,
|
|
61
|
+
/** Expected evidence envelopes. */
|
|
62
|
+
envelopes: z.array(evidenceEnvelopeSchema).min(0).max(100),
|
|
63
|
+
/** Expected evidence bundle. */
|
|
64
|
+
bundle: evidenceBundleSchema.nullable(),
|
|
65
|
+
/** Required dimensions that must be present in the evidence. */
|
|
66
|
+
required_dimensions: z.array(z.string().min(1)).default([]),
|
|
67
|
+
});
|
|
68
|
+
/** Verifier contract describing how to validate conformance. */
|
|
69
|
+
export const verifierContractSchema = z.strictObject({
|
|
70
|
+
scenario_id: scenarioIdSchema,
|
|
71
|
+
/** Dimensions to verify. */
|
|
72
|
+
dimensions: z
|
|
73
|
+
.array(z.strictObject({
|
|
74
|
+
name: z.string().min(1),
|
|
75
|
+
required: z.boolean().default(true),
|
|
76
|
+
comparison: z.enum(["exact", "semantic", "fuzzy"]),
|
|
77
|
+
}))
|
|
78
|
+
.min(1)
|
|
79
|
+
.max(50),
|
|
80
|
+
/** Tolerance for timing differences in milliseconds. */
|
|
81
|
+
timing_tolerance_ms: z.number().int().nonnegative().default(0),
|
|
82
|
+
});
|
|
83
|
+
/** Top-level conformance package manifest. */
|
|
84
|
+
export const conformancePackageSchema = z.strictObject({
|
|
85
|
+
schema_version: z.literal(CONFORMANCE_PACKAGE_VERSION),
|
|
86
|
+
package_id: conformancePackageIdSchema,
|
|
87
|
+
name: z.string().min(1),
|
|
88
|
+
description: z.string().min(1),
|
|
89
|
+
created_at: z.string().datetime(),
|
|
90
|
+
/** Scenario manifests. */
|
|
91
|
+
scenarios: z.array(scenarioManifestSchema).min(1).max(100),
|
|
92
|
+
/** Replay plans keyed by scenario_id. */
|
|
93
|
+
replay_plans: z.array(replayPlanSchema).min(1).max(100),
|
|
94
|
+
/** Shim plans keyed by scenario_id. */
|
|
95
|
+
shim_plans: z.array(shimPlanSchema).default([]),
|
|
96
|
+
/** Expected evidence for each scenario. */
|
|
97
|
+
expected_evidence: z.array(expectedEvidenceSchema).min(1).max(100),
|
|
98
|
+
/** Verifier contracts for each scenario. */
|
|
99
|
+
verifier_contracts: z.array(verifierContractSchema).min(1).max(100),
|
|
100
|
+
});
|
|
101
|
+
/** Validate a conformance package and cross-check internal references. */
|
|
102
|
+
export function validateConformancePackage(input) {
|
|
103
|
+
const parsed = conformancePackageSchema.safeParse(input);
|
|
104
|
+
if (!parsed.success)
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
error: {
|
|
108
|
+
kind: "invalid_package",
|
|
109
|
+
message: parsed.error.issues[0]?.message ?? "invalid package",
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const pkg = parsed.data;
|
|
113
|
+
// Check for duplicate scenario IDs
|
|
114
|
+
const seen = new Set();
|
|
115
|
+
for (const s of pkg.scenarios) {
|
|
116
|
+
if (seen.has(s.scenario_id))
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
error: { kind: "duplicate_scenario", scenario_id: s.scenario_id },
|
|
120
|
+
};
|
|
121
|
+
seen.add(s.scenario_id);
|
|
122
|
+
}
|
|
123
|
+
// Check that replay plans reference existing scenarios
|
|
124
|
+
for (const rp of pkg.replay_plans) {
|
|
125
|
+
if (!seen.has(rp.scenario_id))
|
|
126
|
+
return {
|
|
127
|
+
ok: false,
|
|
128
|
+
error: {
|
|
129
|
+
kind: "scenario_not_found",
|
|
130
|
+
scenario_id: rp.scenario_id,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Check that expected evidence references existing scenarios
|
|
135
|
+
for (const ee of pkg.expected_evidence) {
|
|
136
|
+
if (!seen.has(ee.scenario_id))
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
error: {
|
|
140
|
+
kind: "scenario_not_found",
|
|
141
|
+
scenario_id: ee.scenario_id,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Check that verifier contracts reference existing scenarios
|
|
146
|
+
for (const vc of pkg.verifier_contracts) {
|
|
147
|
+
if (!seen.has(vc.scenario_id))
|
|
148
|
+
return {
|
|
149
|
+
ok: false,
|
|
150
|
+
error: {
|
|
151
|
+
kind: "scenario_not_found",
|
|
152
|
+
scenario_id: vc.scenario_id,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return { ok: true, value: pkg };
|
|
157
|
+
}
|
|
158
|
+
/** Compute a deterministic package ID from the canonical JSON. */
|
|
159
|
+
export function computePackageId(pkg) {
|
|
160
|
+
const json = canonicalize(pkg);
|
|
161
|
+
if (!json)
|
|
162
|
+
throw new Error("failed to canonicalize package");
|
|
163
|
+
return `cp_${createHash("sha256").update(json).digest("hex")}`;
|
|
164
|
+
}
|
|
165
|
+
/** Create a conformance package with an auto-computed package_id. */
|
|
166
|
+
export function createConformancePackage(pkg) {
|
|
167
|
+
const package_id = computePackageId(pkg);
|
|
168
|
+
return { package_id, ...pkg };
|
|
169
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { conformancePackageSchema, } from "./conformancePackage.js";
|
|
3
|
+
import { evaluatePackageTrustGates, trustGateResultSchema, } from "./conformanceTrustGate.js";
|
|
4
|
+
/** Result of a single scenario replay. */
|
|
5
|
+
export const scenarioReplayResultSchema = z.strictObject({
|
|
6
|
+
scenario_id: z.string().min(1),
|
|
7
|
+
status: z.enum(["pass", "fail", "error", "skipped"]),
|
|
8
|
+
exit_code: z.number().int().nullable(),
|
|
9
|
+
duration_ms: z.number().int().nonnegative(),
|
|
10
|
+
output: z.string().default(""),
|
|
11
|
+
error: z.string().nullable(),
|
|
12
|
+
});
|
|
13
|
+
/** Result of replaying an entire conformance package. */
|
|
14
|
+
export const packageReplayResultSchema = z.strictObject({
|
|
15
|
+
package_id: z.string().min(1),
|
|
16
|
+
total_scenarios: z.number().int().positive(),
|
|
17
|
+
passed: z.number().int().nonnegative(),
|
|
18
|
+
failed: z.number().int().nonnegative(),
|
|
19
|
+
errored: z.number().int().nonnegative(),
|
|
20
|
+
skipped: z.number().int().nonnegative(),
|
|
21
|
+
scenario_results: z.array(scenarioReplayResultSchema),
|
|
22
|
+
trust_gate_results: z.array(trustGateResultSchema),
|
|
23
|
+
drift_detected: z.boolean(),
|
|
24
|
+
first_drift: z
|
|
25
|
+
.strictObject({
|
|
26
|
+
scenario_id: z.string().min(1),
|
|
27
|
+
dimension: z.string().min(1),
|
|
28
|
+
evidence_id: z.string().min(1),
|
|
29
|
+
message: z.string(),
|
|
30
|
+
})
|
|
31
|
+
.nullable(),
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Default no-op scenario runner that skips all scenarios.
|
|
35
|
+
* Real CI replays inject an actual runner.
|
|
36
|
+
*/
|
|
37
|
+
async function defaultRunner() {
|
|
38
|
+
return {
|
|
39
|
+
scenario_id: "unknown",
|
|
40
|
+
status: "skipped",
|
|
41
|
+
exit_code: null,
|
|
42
|
+
duration_ms: 0,
|
|
43
|
+
output: "",
|
|
44
|
+
error: "no runner provided",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Replay a conformance package from a clean checkout.
|
|
49
|
+
* Runs each scenario, evaluates trust gates, and detects drift
|
|
50
|
+
* between the captured run and the committed package.
|
|
51
|
+
*/
|
|
52
|
+
export async function replayConformancePackage(packageInput, actualEvidence, runner = defaultRunner, options = {}) {
|
|
53
|
+
const parsed = conformancePackageSchema.safeParse(packageInput);
|
|
54
|
+
if (!parsed.success)
|
|
55
|
+
throw new TypeError(`invalid conformance package: ${parsed.error.issues[0]?.message ?? "unknown"}`);
|
|
56
|
+
const pkg = parsed.data;
|
|
57
|
+
const scenarioResults = [];
|
|
58
|
+
let passed = 0;
|
|
59
|
+
let failed = 0;
|
|
60
|
+
let errored = 0;
|
|
61
|
+
let skipped = 0;
|
|
62
|
+
for (const scenario of pkg.scenarios) {
|
|
63
|
+
const result = await runner(scenario.scenario_id, scenario.fixture_path);
|
|
64
|
+
scenarioResults.push(result);
|
|
65
|
+
switch (result.status) {
|
|
66
|
+
case "pass":
|
|
67
|
+
passed++;
|
|
68
|
+
break;
|
|
69
|
+
case "fail":
|
|
70
|
+
failed++;
|
|
71
|
+
break;
|
|
72
|
+
case "error":
|
|
73
|
+
errored++;
|
|
74
|
+
break;
|
|
75
|
+
case "skipped":
|
|
76
|
+
skipped++;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const trustGateResults = evaluatePackageTrustGates(pkg, actualEvidence, options);
|
|
81
|
+
const driftGates = trustGateResults.filter((r) => r.verdict === "fail");
|
|
82
|
+
const drift_detected = driftGates.length > 0;
|
|
83
|
+
const first_drift_gate = driftGates[0];
|
|
84
|
+
const first_drift = first_drift_gate?.first_divergence
|
|
85
|
+
? {
|
|
86
|
+
scenario_id: first_drift_gate.scenario_id,
|
|
87
|
+
dimension: first_drift_gate.first_divergence.dimension,
|
|
88
|
+
evidence_id: first_drift_gate.first_divergence.evidence_id,
|
|
89
|
+
message: first_drift_gate.first_divergence.message,
|
|
90
|
+
}
|
|
91
|
+
: null;
|
|
92
|
+
return {
|
|
93
|
+
package_id: pkg.package_id,
|
|
94
|
+
total_scenarios: pkg.scenarios.length,
|
|
95
|
+
passed,
|
|
96
|
+
failed,
|
|
97
|
+
errored,
|
|
98
|
+
skipped,
|
|
99
|
+
scenario_results: scenarioResults,
|
|
100
|
+
trust_gate_results: trustGateResults,
|
|
101
|
+
drift_detected,
|
|
102
|
+
first_drift,
|
|
103
|
+
};
|
|
104
|
+
}
|