rea-agents 2.3.0 → 2.5.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.
Files changed (209) hide show
  1. package/README.md +80 -18
  2. package/bridge/ghidra/ReaGhidraBridge.java +48 -1
  3. package/bridge/hopper_bridge.py +259 -24
  4. package/dist/application/AnalysisClientCleanup.js +14 -0
  5. package/dist/application/ApplicationWorkflowEvidenceResolver.js +31 -13
  6. package/dist/application/ArtifactExtraction.js +5 -1
  7. package/dist/application/ArtifactGraphConstruction.js +3 -15
  8. package/dist/application/ArtifactInventory/classify.js +5 -1
  9. package/dist/application/ArtifactInventory/reader.js +2 -0
  10. package/dist/application/BinarySession.js +15 -4
  11. package/dist/application/BinarySessionStatus.js +32 -1
  12. package/dist/application/BrowserEvidence.js +14 -0
  13. package/dist/application/BrowserScenarioCapturePort.js +1 -0
  14. package/dist/application/BrowserScenarioCaptureService.js +53 -0
  15. package/dist/application/BrowserScenarioEvidence.js +40 -0
  16. package/dist/application/CallPathTracing.js +160 -0
  17. package/dist/application/CapabilityInventory.js +79 -15
  18. package/dist/application/CompositeProvider.js +10 -1
  19. package/dist/application/DirectAnalysis.js +7 -2
  20. package/dist/application/EnhancedLiteralTracing.js +118 -0
  21. package/dist/application/EnhancedTools.js +35 -121
  22. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +13 -0
  23. package/dist/application/JavaScriptApplicationWorkflowService.js +27 -1
  24. package/dist/application/JavaScriptRuntimeObservationEvidence.js +34 -0
  25. package/dist/application/JavaScriptRuntimeObservationPort.js +1 -0
  26. package/dist/application/JavaScriptRuntimeObservationService.js +46 -0
  27. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +147 -0
  28. package/dist/application/JavaScriptSemanticGraphBuilder.js +34 -6
  29. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +156 -0
  30. package/dist/application/JavaScriptSemanticGraphConstruction.js +2 -2
  31. package/dist/application/JavaScriptSemanticGraphDataProjection.js +203 -0
  32. package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
  33. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +129 -8
  34. package/dist/application/JavaScriptSemanticGraphObjectProjection.js +81 -0
  35. package/dist/application/JavaScriptSemanticGraphProjection.js +14 -7
  36. package/dist/application/JavaScriptSemanticGraphResourceProjection.js +59 -0
  37. package/dist/application/JavaScriptSemanticGraphValueProjection.js +77 -0
  38. package/dist/application/ProcessCaptureEnvironment.js +26 -0
  39. package/dist/application/ProcessCaptureLifecycle.js +1 -0
  40. package/dist/application/ProcessCheckpoints.js +5 -0
  41. package/dist/application/ProcessHarness.js +45 -34
  42. package/dist/application/ProcessNormalization.js +6 -0
  43. package/dist/application/ProcessReactiveCoordinator.js +10 -3
  44. package/dist/application/ProcessReactiveEffects.js +15 -1
  45. package/dist/application/ProcessReactiveHarness.js +100 -0
  46. package/dist/application/ProcessReactiveObservations.js +101 -16
  47. package/dist/application/ProjectPermissionStore.js +1 -0
  48. package/dist/application/ReconstructionObligationAuthority.js +72 -0
  49. package/dist/application/ReconstructionObligationCandidates.js +265 -0
  50. package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
  51. package/dist/application/ReconstructionObligationLedgerEvaluation.js +263 -0
  52. package/dist/application/ReconstructionObligationLedgerProjection.js +86 -0
  53. package/dist/application/ReconstructionObligationLedgerService.js +72 -0
  54. package/dist/application/ReconstructionObligationOriginalCases.js +33 -0
  55. package/dist/application/ReconstructionObligationPolicies.js +132 -0
  56. package/dist/application/ReconstructionReadinessService.js +48 -0
  57. package/dist/artifacts/ArtifactProvider.js +87 -22
  58. package/dist/browser/BrowserScenarioSecrets.js +53 -0
  59. package/dist/browser/BrowserScenarioSessionPort.js +1 -0
  60. package/dist/browser/CdpBrowserProvider.js +2 -2
  61. package/dist/browser/CdpCaptureDocuments.js +57 -0
  62. package/dist/browser/CdpCaptureStorage.js +71 -29
  63. package/dist/browser/CdpCaptureStorageFingerprints.js +328 -0
  64. package/dist/browser/CdpEndpoint.js +8 -6
  65. package/dist/browser/CdpPageCapture.js +2 -0
  66. package/dist/browser/JavaScriptRuntimeScope.js +38 -0
  67. package/dist/browser/PlaywrightBrowserScenarioProvider.js +253 -0
  68. package/dist/browser/PlaywrightExecutionBoundary.js +42 -0
  69. package/dist/browser/PlaywrightScenarioActions.js +62 -0
  70. package/dist/browser/PlaywrightScenarioArtifacts.js +238 -0
  71. package/dist/browser/PlaywrightScenarioBrowser.js +144 -0
  72. package/dist/browser/PlaywrightScenarioEvents.js +301 -0
  73. package/dist/browser/PlaywrightScenarioSession.js +300 -0
  74. package/dist/browser/V8InspectorCaptureProjection.js +110 -0
  75. package/dist/browser/V8InspectorEndpoint.js +72 -0
  76. package/dist/browser/V8InspectorProvider.js +267 -0
  77. package/dist/catalogIdentity.js +8 -0
  78. package/dist/cli/artifactCommands.js +39 -0
  79. package/dist/cli/coreAnalysisCommands.js +37 -0
  80. package/dist/cli.js +4 -0
  81. package/dist/cliApplicationCommands.js +30 -2
  82. package/dist/cliBrowserAdvancedCommands.js +17 -5
  83. package/dist/cliBrowserCommands.js +1 -0
  84. package/dist/cliBrowserScenarioCommands.js +43 -0
  85. package/dist/cliCommandNames.js +8 -0
  86. package/dist/cliJavaScriptRuntimeCommands.js +164 -0
  87. package/dist/cliObservationOptions.js +4 -0
  88. package/dist/cliPolicyCommands.js +1 -0
  89. package/dist/config/environment.js +12 -0
  90. package/dist/config/parseConfig.js +88 -17
  91. package/dist/contracts/analysisSearchContract.js +14 -0
  92. package/dist/contracts/applicationToolContracts.js +86 -2
  93. package/dist/contracts/applicationWorkflowInputContracts.js +18 -0
  94. package/dist/contracts/artifactToolContracts.js +22 -0
  95. package/dist/contracts/browserProviderToolContracts.js +7 -0
  96. package/dist/contracts/browserScenarioToolContracts.js +81 -0
  97. package/dist/contracts/browserToolContracts.js +88 -98
  98. package/dist/contracts/enhancedInputs.js +25 -6
  99. package/dist/contracts/functionInstructionContract.js +8 -0
  100. package/dist/contracts/hopperMemoryContracts.js +22 -0
  101. package/dist/contracts/javascriptApplicationWorkflowExamples.js +42 -0
  102. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +58 -0
  103. package/dist/contracts/reconstructionReadinessExample.js +436 -0
  104. package/dist/contracts/toolContractExamples.js +5 -0
  105. package/dist/contracts/toolContractTypes.js +1 -0
  106. package/dist/contracts/toolContracts.js +13 -21
  107. package/dist/contracts/toolEffects.js +21 -0
  108. package/dist/contracts/toolOutputSchemaGroups.js +70 -20
  109. package/dist/contracts/toolOutputSchemaPrimitives.js +40 -0
  110. package/dist/domain/analysisErrorProjection.js +8 -0
  111. package/dist/domain/analysisSnapshot.js +2 -0
  112. package/dist/domain/artifactGraph.js +2 -0
  113. package/dist/domain/artifactInspection.js +347 -0
  114. package/dist/domain/binaryTarget.js +3 -6
  115. package/dist/domain/browserCaptureComparison.js +82 -0
  116. package/dist/domain/browserObservation.js +8 -1
  117. package/dist/domain/browserObservationErrors.js +1 -0
  118. package/dist/domain/browserObservationSchemas.js +26 -0
  119. package/dist/domain/browserScenario.js +165 -0
  120. package/dist/domain/browserScenarioCapture.js +57 -0
  121. package/dist/domain/browserScenarioCaptureValues.js +204 -0
  122. package/dist/domain/browserScenarioDiff.js +324 -0
  123. package/dist/domain/browserScenarioDiffValues.js +157 -0
  124. package/dist/domain/browserScenarioNormalization.js +45 -0
  125. package/dist/domain/browserScenarioValues.js +372 -0
  126. package/dist/domain/evidence.js +2 -0
  127. package/dist/domain/hopperValues.js +10 -0
  128. package/dist/domain/javascriptRuntimeObservation.js +170 -0
  129. package/dist/domain/javascriptRuntimeReconciliationParsing.js +120 -2
  130. package/dist/domain/javascriptRuntimeReconciliationResult.js +3 -3
  131. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +2 -2
  132. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  133. package/dist/domain/javascriptSemanticAnalysis.js +5 -4
  134. package/dist/domain/javascriptSemanticAsyncEffects.js +253 -0
  135. package/dist/domain/javascriptSemanticChildProcesses.js +237 -0
  136. package/dist/domain/javascriptSemanticDataEffectHelpers.js +125 -0
  137. package/dist/domain/javascriptSemanticDataEffects.js +284 -0
  138. package/dist/domain/javascriptSemanticDerivedAnalysis.js +41 -0
  139. package/dist/domain/javascriptSemanticFingerprints.js +174 -0
  140. package/dist/domain/javascriptSemanticIr.js +21 -1
  141. package/dist/domain/javascriptSemanticObjects.js +115 -0
  142. package/dist/domain/javascriptSemanticPromises.js +290 -0
  143. package/dist/domain/javascriptSemanticResources.js +136 -0
  144. package/dist/domain/javascriptStaticAnalysis.js +4 -3
  145. package/dist/domain/javascriptStaticAnalysisBundler.js +38 -0
  146. package/dist/domain/javascriptStaticAnalysisCalls.js +23 -1
  147. package/dist/domain/javascriptStaticAnalysisHelpers.js +8 -0
  148. package/dist/domain/processCapture.js +71 -1
  149. package/dist/domain/processCaptureReactiveValidation.js +175 -0
  150. package/dist/domain/processCaptureValidation.js +2 -0
  151. package/dist/domain/processObservation.js +15 -6
  152. package/dist/domain/processReactiveRuntime.js +21 -10
  153. package/dist/domain/processReactiveScenario.js +1 -0
  154. package/dist/domain/processReactiveTransition.js +17 -10
  155. package/dist/domain/processScenario.js +21 -0
  156. package/dist/domain/providerCleanupError.js +11 -0
  157. package/dist/domain/reconstructionObligationLedgerSchemas.js +278 -0
  158. package/dist/domain/reconstructionReadiness.js +121 -0
  159. package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
  160. package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
  161. package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
  162. package/dist/domain/reconstructionReadinessSchemas.js +240 -0
  163. package/dist/domain/sourceToBundleComparison.js +335 -0
  164. package/dist/domain/sourceToBundleComparisonSchemas.js +133 -0
  165. package/dist/domain/sourceToBundleSignals.js +202 -0
  166. package/dist/domain/webCaptureDiff.js +141 -27
  167. package/dist/domain/webScreenshot.js +1 -1
  168. package/dist/domain/zipPackageFormat.js +20 -0
  169. package/dist/generatedPackageMetadata.js +1 -1
  170. package/dist/ghidra/GhidraDefaults.js +1 -1
  171. package/dist/ghidra/GhidraFunctionValues.js +13 -1
  172. package/dist/ghidra/GhidraProviderCapabilities.js +7 -0
  173. package/dist/hopper/HopperCleanup.js +158 -0
  174. package/dist/hopper/HopperClient.js +69 -99
  175. package/dist/hopper/HopperProvider.js +20 -1
  176. package/dist/hopper/HopperRequestQueue.js +187 -0
  177. package/dist/hopper/HopperResponseStream.js +46 -0
  178. package/dist/hopper/protocol.js +1 -0
  179. package/dist/main/transport.js +24 -24
  180. package/dist/main.js +6 -0
  181. package/dist/mcpDoctor.js +25 -2
  182. package/dist/native/NativeMacOSProvider.js +1 -0
  183. package/dist/process/ProcessCommandIdentity.js +19 -0
  184. package/dist/process/ProcessOwnership.js +11 -8
  185. package/dist/server/DynamicToolAvailability.js +70 -0
  186. package/dist/server/createServer.js +46 -1
  187. package/dist/server/lifecycleProgress.js +10 -0
  188. package/dist/server/permissionFailure.js +12 -0
  189. package/dist/server/registerApplicationTools/compareSourceToBundle.js +35 -0
  190. package/dist/server/registerApplicationTools/helpers.js +11 -7
  191. package/dist/server/registerApplicationTools/obligationLedger.js +27 -0
  192. package/dist/server/registerApplicationTools/readiness.js +55 -0
  193. package/dist/server/registerApplicationTools.js +6 -0
  194. package/dist/server/registerArtifactTools.js +9 -1
  195. package/dist/server/registerBrowserScenarioTool.js +25 -0
  196. package/dist/server/registerBrowserTools.js +2 -2
  197. package/dist/server/registerCloseLifecycleTool.js +57 -0
  198. package/dist/server/registerEnhancedTools.js +16 -5
  199. package/dist/server/registerEvidenceResources.js +4 -0
  200. package/dist/server/registerEvidenceTools.js +9 -2
  201. package/dist/server/registerJavaScriptRuntimeObservationTools.js +37 -0
  202. package/dist/server/registerReconstructionObligationLedgerResource.js +39 -0
  203. package/dist/server/registerReconstructionReadinessResource.js +39 -0
  204. package/dist/server/registerSessionStatusTool.js +11 -8
  205. package/dist/server/registerSessionTools.js +11 -57
  206. package/dist/server/sessionAvailabilityPolicy.js +10 -8
  207. package/package.json +12 -6
  208. package/skills/reverse-engineer-anything/SKILL.md +4 -3
  209. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +2 -2
@@ -1,20 +1,105 @@
1
- import { createProcessObservation } from "../domain/processObservation.js";
2
- /** Subscribe a reactive coordinator to normalized raw PTY journal records. */
3
- export const subscribeProcessReactiveTerminalObservations = (options) => options.journal.subscribe((entry) => {
4
- if (entry.collection !== "frames")
5
- return;
6
- const frame = options.frames[entry.index];
7
- if (frame === undefined)
8
- return;
9
- options.sink.enqueue({
10
- kind: "observation",
11
- observation: createProcessObservation({
1
+ import { createProcessObservation, processObservationSubject, } from "../domain/processObservation.js";
2
+ const terminalObservation = (options, entry) => {
3
+ const value = options.frames[entry.index];
4
+ return value === undefined
5
+ ? undefined
6
+ : createProcessObservation({
12
7
  source: "terminal_raw",
13
- source_sequence: frame.sequence,
14
- captured_at_ms: frame.at_ms,
8
+ source_sequence: value.sequence,
9
+ captured_at_ms: value.at_ms,
15
10
  subject_id: null,
16
11
  location: entry,
17
- payload: frame,
18
- }),
12
+ payload: value,
13
+ });
14
+ };
15
+ const interactionObservation = (options, entry) => {
16
+ const value = options.interactions[entry.index];
17
+ return value === undefined
18
+ ? undefined
19
+ : createProcessObservation({
20
+ source: "interaction",
21
+ source_sequence: value.sequence,
22
+ captured_at_ms: value.dispatched_at_ms,
23
+ subject_id: null,
24
+ location: entry,
25
+ payload: value,
26
+ });
27
+ };
28
+ const filesystemObservation = (options, entry) => {
29
+ const value = options.checkpointAt(entry.index);
30
+ return value === undefined
31
+ ? undefined
32
+ : createProcessObservation({
33
+ source: "filesystem",
34
+ source_sequence: entry.index,
35
+ captured_at_ms: value.at_ms,
36
+ subject_id: processObservationSubject("filesystem", value),
37
+ location: entry,
38
+ payload: value,
39
+ });
40
+ };
41
+ const processObservation = (options, entry) => {
42
+ const value = options.processSampleAt(entry.index);
43
+ return value === undefined
44
+ ? undefined
45
+ : createProcessObservation({
46
+ source: "process",
47
+ source_sequence: entry.index,
48
+ captured_at_ms: value.at_ms,
49
+ subject_id: processObservationSubject("process", value),
50
+ location: entry,
51
+ payload: value,
52
+ });
53
+ };
54
+ const protocolObservation = (options, entry) => {
55
+ const value = options.protocolEventAt(entry.index);
56
+ return value === undefined
57
+ ? undefined
58
+ : createProcessObservation({
59
+ source: value.protocol,
60
+ source_sequence: value.sequence,
61
+ captured_at_ms: value.at_ms,
62
+ subject_id: processObservationSubject(value.protocol, value),
63
+ location: entry,
64
+ payload: value,
65
+ });
66
+ };
67
+ const shimObservation = (options, entry) => {
68
+ const normalized = options.shimEventAt(entry.index);
69
+ if (normalized === undefined)
70
+ return undefined;
71
+ return createProcessObservation({
72
+ source: "shim",
73
+ source_sequence: normalized.sequence,
74
+ captured_at_ms: normalized.at_ms,
75
+ subject_id: processObservationSubject("shim", normalized),
76
+ location: entry,
77
+ payload: normalized,
19
78
  });
20
- });
79
+ };
80
+ const observationFor = (options, entry) => {
81
+ if (entry.collection === "frames")
82
+ return terminalObservation(options, entry);
83
+ if (entry.collection === "interaction_events")
84
+ return interactionObservation(options, entry);
85
+ if (entry.collection === "filesystem_checkpoints")
86
+ return filesystemObservation(options, entry);
87
+ if (entry.collection === "process_samples")
88
+ return processObservation(options, entry);
89
+ if (entry.collection === "protocol_events")
90
+ return protocolObservation(options, entry);
91
+ if (entry.collection === "shim_events")
92
+ return shimObservation(options, entry);
93
+ return undefined;
94
+ };
95
+ /** Subscribe the reactive coordinator to admitted normalized journal records. */
96
+ export const subscribeProcessReactiveObservations = (options) => {
97
+ const enqueue = (entry) => {
98
+ const observation = observationFor(options, entry);
99
+ if (observation !== undefined)
100
+ options.sink.enqueue({ kind: "observation", observation });
101
+ };
102
+ for (const entry of options.journal.entries)
103
+ enqueue(entry);
104
+ return options.journal.subscribe(enqueue);
105
+ };
@@ -11,6 +11,7 @@ const grantSchema = z.object({
11
11
  capability: z.enum([
12
12
  "process_capture",
13
13
  "browser_observe",
14
+ "browser_automate",
14
15
  "electron_observe",
15
16
  "evidence_read",
16
17
  "evidence_write",
@@ -0,0 +1,72 @@
1
+ const proofEvidenceAuthorities = {
2
+ unit: ["shipped-artifact", "controlled-replay"],
3
+ integration: ["controlled-replay"],
4
+ protocol: ["controlled-replay", "external-service"],
5
+ renderer: ["controlled-replay", "external-service"],
6
+ "packaged-process": ["controlled-replay"],
7
+ "native-abi": ["shipped-artifact", "controlled-replay"],
8
+ "live-observation": ["controlled-replay", "external-service"],
9
+ external: ["external-service"],
10
+ };
11
+ /** Return whether an actual reconstruction proof is comparable to a requirement. */
12
+ export const proofAuthoritySatisfies = (actual, required) => {
13
+ const accepted = {
14
+ unit: [
15
+ "unit",
16
+ "integration",
17
+ "protocol",
18
+ "renderer",
19
+ "packaged-process",
20
+ "native-abi",
21
+ "live-observation",
22
+ "external",
23
+ ],
24
+ integration: [
25
+ "integration",
26
+ "protocol",
27
+ "renderer",
28
+ "packaged-process",
29
+ "native-abi",
30
+ "live-observation",
31
+ ],
32
+ protocol: ["protocol", "packaged-process", "live-observation"],
33
+ renderer: ["renderer", "packaged-process", "live-observation"],
34
+ "packaged-process": ["packaged-process", "live-observation"],
35
+ "native-abi": ["native-abi"],
36
+ "live-observation": ["live-observation"],
37
+ external: ["external"],
38
+ };
39
+ return accepted[required].includes(actual);
40
+ };
41
+ /** Check that Evidence can authenticate the declared reconstruction authority. */
42
+ export const evidenceAuthoritySupportsProof = (evidence, authority, expected) => {
43
+ if (evidence.confidence !== "observed" ||
44
+ !proofEvidenceAuthorities[authority].includes(evidence.authority) ||
45
+ evidence.predicate_type !== "rea.reconstruction-proof/v1" ||
46
+ evidence.operation !== "verify_reconstruction_obligations")
47
+ return false;
48
+ const result = evidence.normalized_result;
49
+ if (typeof result !== "object" || result === null || Array.isArray(result))
50
+ return false;
51
+ const includes = (key, value) => value === undefined ||
52
+ (Array.isArray(result[key]) && result[key].includes(value));
53
+ return (result.passed === true &&
54
+ includes("obligation_ids", expected.obligationId) &&
55
+ includes("fixture_ids", expected.fixtureId) &&
56
+ includes("case_kinds", expected.caseKind) &&
57
+ includes("verifier_ids", expected.verifierId) &&
58
+ includes("claim_ids", expected.claimId));
59
+ };
60
+ /** Check that Evidence observes the original at the required boundary. */
61
+ export const evidenceSupportsOriginalAuthority = (evidence, authority) => {
62
+ if (evidence.confidence !== "observed")
63
+ return false;
64
+ if (authority === "static")
65
+ return evidence.authority === "shipped-artifact";
66
+ if (authority === "runtime")
67
+ return ["controlled-replay", "external-service"].includes(evidence.authority);
68
+ if (authority === "process")
69
+ return (evidence.operation === "capture_process_scenario" &&
70
+ evidence.predicate_type === "rea.process-capture/v4");
71
+ return evidence.authority === "external-service";
72
+ };
@@ -0,0 +1,265 @@
1
+ import { createHash } from "node:crypto";
2
+ import canonicalize from "canonicalize";
3
+ import { parseEvidenceBundle, } from "../domain/evidenceBundle.js";
4
+ import { parseProcessCapture } from "../domain/processCapture.js";
5
+ import { parseApplicationGraphEvidence } from "./JavaScriptApplicationEvidenceGraph.js";
6
+ import { applicationObligationPolicy, semanticObligationPolicy, } from "./ReconstructionObligationPolicies.js";
7
+ /** Derive conservative candidates from graph, process, and reviewed inputs. */
8
+ export const deriveReconstructionObligationCandidates = (bundleInput, reviewed) => {
9
+ const bundle = parseEvidenceBundle(bundleInput);
10
+ const records = new Map(bundle.records.map((record) => [record.evidence_id, record]));
11
+ const candidates = new Map();
12
+ const limitations = new Set();
13
+ for (const evidence of bundle.records) {
14
+ deriveApplicationCandidates(evidence, records, candidates, limitations);
15
+ deriveProcessCandidate(evidence, candidates, limitations);
16
+ }
17
+ for (const obligation of reviewed)
18
+ addCandidate(candidates, reviewedCandidate(obligation, records));
19
+ return {
20
+ candidates: [...candidates.values()].sort((left, right) => left.obligation_id.localeCompare(right.obligation_id)),
21
+ limitations: [...limitations].sort(),
22
+ };
23
+ };
24
+ const deriveApplicationCandidates = (evidence, records, candidates, limitations) => {
25
+ if (![
26
+ "analyze_javascript_application",
27
+ "reconcile_javascript_runtime",
28
+ "project_managed_application_graph",
29
+ ].includes(evidence.operation))
30
+ return;
31
+ try {
32
+ const source = parseApplicationGraphEvidence(evidence);
33
+ for (const node of source.graph.nodes) {
34
+ const candidatePolicy = applicationObligationPolicy(node.kind);
35
+ if (candidatePolicy === undefined)
36
+ continue;
37
+ const reference = node.observations.map((observation) => graphReference(evidence, records, observation.evidence, `${source.graph.graph_id}/node/${node.node_id}/observation/${observation.observation_id}`));
38
+ addCandidate(candidates, generatedCandidate({
39
+ key: `application:${node.node_id}:${candidatePolicy.family}`,
40
+ title: node.observations[0]?.label ?? `${node.kind} boundary`,
41
+ policy: candidatePolicy,
42
+ artifactSha256: source.rootArtifactSha256,
43
+ applicationNodeId: node.node_id,
44
+ semanticNodeId: null,
45
+ location: `application-graph:${source.graph.graph_id}/nodes/${node.node_id}`,
46
+ authorityReferences: reference,
47
+ }));
48
+ }
49
+ if (source.semanticGraph !== null)
50
+ for (const node of source.semanticGraph.nodes) {
51
+ const candidatePolicy = semanticObligationPolicy(node.kind);
52
+ if (candidatePolicy === undefined)
53
+ continue;
54
+ addCandidate(candidates, generatedCandidate({
55
+ key: `semantic:${node.node_id}:${candidatePolicy.family}`,
56
+ title: node.label ?? `${node.kind} semantic boundary`,
57
+ policy: candidatePolicy,
58
+ artifactSha256: node.identity.artifact_sha256,
59
+ applicationNodeId: node.application_node_ids[0] ?? null,
60
+ semanticNodeId: node.node_id,
61
+ location: `semantic-graph:${source.semanticGraph.graph_id}/nodes/${node.node_id}`,
62
+ authorityReferences: [
63
+ graphReference(evidence, records, node.evidence, `${source.semanticGraph.graph_id}/node/${node.node_id}`),
64
+ ],
65
+ }));
66
+ }
67
+ if (source.graph.coverage.status !== "complete")
68
+ limitations.add(`Application graph ${source.graph.graph_id} coverage is ${source.graph.coverage.status}; omitted candidates remain unknown.`);
69
+ }
70
+ catch (cause) {
71
+ limitations.add(`Application Evidence ${evidence.evidence_id} could not generate candidates: ${errorMessage(cause)}`);
72
+ }
73
+ };
74
+ const deriveProcessCandidate = (evidence, candidates, limitations) => {
75
+ if (evidence.operation !== "capture_process_scenario" ||
76
+ evidence.predicate_type !== "rea.process-capture/v4")
77
+ return;
78
+ try {
79
+ const capture = parseProcessCapture(evidence.normalized_result);
80
+ const observedCases = [
81
+ {
82
+ kind: capture.exit.code === 0 ? "positive" : "negative",
83
+ evidence_id: evidence.evidence_id,
84
+ location: "/normalized_result/exit",
85
+ },
86
+ {
87
+ kind: "teardown",
88
+ evidence_id: evidence.evidence_id,
89
+ location: "/normalized_result/settlement",
90
+ },
91
+ ...(capture.exit.signal !== null || capture.exit.reason !== "exited"
92
+ ? [
93
+ {
94
+ kind: "cancellation",
95
+ evidence_id: evidence.evidence_id,
96
+ location: "/normalized_result/exit",
97
+ },
98
+ ]
99
+ : []),
100
+ ];
101
+ addCandidate(candidates, {
102
+ obligation_id: obligationId(`process:${capture.manifest.executable_sha256}:${capture.manifest.full_scenario_sha256}`),
103
+ obligation_version: 1,
104
+ title: "Captured packaged-process lifecycle",
105
+ origin: "generated",
106
+ application_layer: "process",
107
+ family: "packaged-process-lifecycle",
108
+ target: {
109
+ artifact_sha256: capture.manifest.executable_sha256,
110
+ application_node_id: null,
111
+ semantic_node_id: null,
112
+ location: `/evidence/${evidence.evidence_id}/normalized_result`,
113
+ },
114
+ authority_references: [
115
+ {
116
+ evidence_id: evidence.evidence_id,
117
+ authority: evidence.authority,
118
+ state: "observed",
119
+ location: "/normalized_result",
120
+ },
121
+ ],
122
+ source_state: "observed",
123
+ observed_cases: observedCases,
124
+ required: true,
125
+ required_case_kinds: ["positive", "negative", "cancellation", "teardown"],
126
+ required_original_authority: "process",
127
+ required_fixture_authority: "packaged-process",
128
+ required_verifier_authority: "packaged-process",
129
+ requires_parser_type: false,
130
+ dependency_obligation_ids: [],
131
+ residual_unknown_ids: [],
132
+ unavailable_authority: capture.residual_unknowns.map(({ scope, reason }) => `${scope}: ${reason}`),
133
+ required_next_evidence: capture.truncated
134
+ ? ["Repeat the packaged-process capture without truncation."]
135
+ : [],
136
+ definitionCount: 1,
137
+ disposition: "active",
138
+ });
139
+ if (capture.truncated)
140
+ limitations.add(`Process Evidence ${evidence.evidence_id} is truncated; absence and upper bounds remain unknown.`);
141
+ }
142
+ catch (cause) {
143
+ limitations.add(`Process Evidence ${evidence.evidence_id} could not generate candidates: ${errorMessage(cause)}`);
144
+ }
145
+ };
146
+ const generatedCandidate = ({ key, title, policy: candidatePolicy, artifactSha256, applicationNodeId, semanticNodeId, location, authorityReferences, }) => ({
147
+ obligation_id: obligationId(key),
148
+ obligation_version: 1,
149
+ title: title.slice(0, 500),
150
+ origin: "generated",
151
+ application_layer: candidatePolicy.applicationLayer,
152
+ family: candidatePolicy.family,
153
+ target: {
154
+ artifact_sha256: artifactSha256,
155
+ application_node_id: applicationNodeId,
156
+ semantic_node_id: semanticNodeId,
157
+ location,
158
+ },
159
+ authority_references: authorityReferences,
160
+ source_state: sourceState(authorityReferences),
161
+ observed_cases: [],
162
+ required: true,
163
+ required_case_kinds: candidatePolicy.cases,
164
+ required_original_authority: candidatePolicy.originalAuthority,
165
+ required_fixture_authority: candidatePolicy.fixtureAuthority,
166
+ required_verifier_authority: candidatePolicy.verifierAuthority,
167
+ requires_parser_type: candidatePolicy.requiresParserType,
168
+ dependency_obligation_ids: [],
169
+ residual_unknown_ids: [],
170
+ unavailable_authority: [],
171
+ required_next_evidence: [
172
+ `Obtain ${candidatePolicy.originalAuthority} authority for this finite ${candidatePolicy.family} claim.`,
173
+ ],
174
+ definitionCount: 1,
175
+ disposition: "active",
176
+ });
177
+ const reviewedCandidate = (obligation, records) => {
178
+ const { review_evidence_ids: reviewEvidenceIds, disposition, ...definition } = obligation;
179
+ return {
180
+ ...definition,
181
+ origin: "reviewed",
182
+ authority_references: reviewEvidenceIds.map((evidenceId) => {
183
+ const evidence = records.get(evidenceId);
184
+ if (evidence === undefined)
185
+ throw new TypeError(`Reviewed obligation Evidence is missing: ${evidenceId}`);
186
+ return {
187
+ evidence_id: evidenceId,
188
+ authority: evidence.authority,
189
+ state: reviewedEvidenceState(evidence),
190
+ location: `/evidence/${evidenceId}`,
191
+ };
192
+ }),
193
+ source_state: "reviewed",
194
+ observed_cases: [],
195
+ definitionCount: 1,
196
+ disposition,
197
+ };
198
+ };
199
+ const graphReference = (envelope, records, graphEvidence, location) => {
200
+ const linkedId = graphEvidence.evidence_ids.find((evidenceId) => records.has(evidenceId)) ??
201
+ envelope.evidence_id;
202
+ const linked = records.get(linkedId) ?? envelope;
203
+ const runtimeAuthority = [
204
+ "passive-cdp-runtime",
205
+ "controlled-replay",
206
+ ].includes(graphEvidence.authority);
207
+ return {
208
+ evidence_id: linked.evidence_id,
209
+ authority: linked.authority,
210
+ state: runtimeAuthority && graphEvidence.state === "observed"
211
+ ? "observed"
212
+ : graphEvidence.state === "unknown" ||
213
+ graphEvidence.state === "unavailable"
214
+ ? "unknown"
215
+ : "candidate",
216
+ location,
217
+ };
218
+ };
219
+ const reviewedEvidenceState = (evidence) => {
220
+ if (evidence.operation === "capture_process_scenario" &&
221
+ evidence.predicate_type === "rea.process-capture/v4" &&
222
+ evidence.confidence === "observed")
223
+ return "observed";
224
+ if (evidence.authority === "external-service" &&
225
+ evidence.confidence === "observed")
226
+ return "observed";
227
+ if (evidence.authority === "shipped-artifact")
228
+ return "candidate";
229
+ return "reviewed";
230
+ };
231
+ const addCandidate = (candidates, candidate) => {
232
+ const current = candidates.get(candidate.obligation_id);
233
+ if (current === undefined) {
234
+ candidates.set(candidate.obligation_id, candidate);
235
+ return;
236
+ }
237
+ candidates.set(candidate.obligation_id, {
238
+ ...current,
239
+ authority_references: uniqueBy([...current.authority_references, ...candidate.authority_references], (reference) => `${reference.evidence_id}:${reference.state}:${reference.location}`),
240
+ observed_cases: uniqueBy([...current.observed_cases, ...candidate.observed_cases], (item) => `${item.kind}:${item.evidence_id}:${item.location}`),
241
+ source_state: sourceState([
242
+ ...current.authority_references,
243
+ ...candidate.authority_references,
244
+ ]),
245
+ definitionCount: current.definitionCount + candidate.definitionCount,
246
+ });
247
+ };
248
+ const sourceState = (references) => {
249
+ if (references.some(({ state }) => state === "observed"))
250
+ return "observed";
251
+ if (references.some(({ state }) => state === "candidate"))
252
+ return "candidate";
253
+ if (references.some(({ state }) => state === "reviewed"))
254
+ return "reviewed";
255
+ return "unknown";
256
+ };
257
+ const uniqueBy = (values, key) => [...new Map(values.map((value) => [key(value), value])).values()].sort((left, right) => key(left).localeCompare(key(right)));
258
+ const obligationId = (key) => `obl_${digest({ schema: "rea.reconstruction-obligation/v1", key })}`;
259
+ const digest = (value) => {
260
+ const encoded = canonicalize(value);
261
+ if (encoded === undefined)
262
+ throw new TypeError("Reconstruction obligation key is not canonical JSON");
263
+ return createHash("sha256").update(encoded).digest("hex");
264
+ };
265
+ const errorMessage = (cause) => cause instanceof Error ? cause.message : "unknown validation failure";
@@ -0,0 +1,47 @@
1
+ export const groupManifestBindings = (manifest) => {
2
+ const grouped = new Map();
3
+ for (const binding of manifest.bindings)
4
+ grouped.set(binding.obligation_id, [
5
+ ...(grouped.get(binding.obligation_id) ?? []),
6
+ binding,
7
+ ]);
8
+ return grouped;
9
+ };
10
+ export const groupManifestContradictions = (manifest) => {
11
+ const grouped = new Map();
12
+ for (const contradiction of manifest.contradictions)
13
+ grouped.set(contradiction.obligation_id, [
14
+ ...(grouped.get(contradiction.obligation_id) ?? []),
15
+ ...contradiction.evidence_ids,
16
+ ]);
17
+ return grouped;
18
+ };
19
+ export const addObligationDiagnostic = (diagnostics, code, detail) => {
20
+ diagnostics.push({ code, detail });
21
+ };
22
+ export const uniqueObligationDiagnostics = (diagnostics) => [
23
+ ...new Map(diagnostics.map((diagnostic) => [
24
+ `${diagnostic.code}:${diagnostic.detail}`,
25
+ diagnostic,
26
+ ])).values(),
27
+ ].sort((left, right) => `${left.code}:${left.detail}`.localeCompare(`${right.code}:${right.detail}`));
28
+ export const hasObligationDiagnostic = (diagnostics, code) => diagnostics.some((diagnostic) => diagnostic.code === code);
29
+ export const contradictionDiagnostics = (obligationId, contradictions, evidenceById) => {
30
+ const evidenceIds = contradictions.get(obligationId) ?? [];
31
+ if (evidenceIds.length === 0)
32
+ return [];
33
+ const missing = evidenceIds.filter((evidenceId) => !evidenceById.has(evidenceId));
34
+ return missing.length > 0
35
+ ? [
36
+ {
37
+ code: "contradiction-evidence-missing",
38
+ detail: `Contradiction references missing Evidence: ${missing.join(", ")}.`,
39
+ },
40
+ ]
41
+ : [
42
+ {
43
+ code: "contradiction",
44
+ detail: "Authenticated contradictory Evidence reopens this obligation.",
45
+ },
46
+ ];
47
+ };