# JavaScript static/runtime reconciliation REA can combine an existing static JavaScript Application Graph with one or more passive browser, Electron page, or Node/Electron V8 Inspector captures without collapsing their different authorities. The `reconcile_javascript_runtime` MCP tool and `rea reconcile-javascript-runtime` CLI command accept Evidence v2 records and return derived Evidence v2 containing a combined JavaScript Application Graph and explicit match, ambiguity, mismatch, and unknown classifications. The operation performs no filesystem, browser, or Electron I/O. It accepts only semantically verified Evidence produced by `analyze_javascript_application`, `inspect_web_page`, `inspect_electron_page`, or `observe_javascript_runtime`; matching operation names alone is insufficient. Provider identity, predicate version, subject digest, target parameters, and normalized-result schemas are checked before reconciliation. ## Workflow 1. Run `analyze_javascript_application` against exactly one application layer. Optional cache or assets directories can be analyzed independently and supplied as additional layers. 2. Run `inspect_web_page`, `inspect_electron_page`, or the attach-only `observe_javascript_runtime`. Capturing script sources is optional, but an approved source capture provides the strongest byte identity. 3. Pass the resulting Evidence records to `reconcile_javascript_runtime`. Browser URLs normally need an explicit URL-prefix mapping. Extracted Electron and V8 Inspector file locations are mapped automatically when runtime files remain beneath the analyzed input root; relocated files, ASAR projections, caches, and asset roots need explicit mappings. The MCP input has this shape; the `analysis` and `runtime_observations` values are complete Evidence v2 objects, not only evidence IDs: ```json { "static_layers": [ { "role": "application", "analysis": "ANALYZE_JAVASCRIPT_APPLICATION_EVIDENCE", "runtime_mappings": [ { "kind": "url-prefix", "prefix": "https://example.test/assets/", "artifact_prefix": "dist" } ] } ], "runtime_observations": ["INSPECT_WEB_PAGE_EVIDENCE"], "limits": { "max_runtime_entities": 10000, "max_reconciliation_items": 20000, "max_static_load_states": 20000 } } ``` `static_layers` requires exactly one `application` role and permits additional `cache` and `assets` roles. A `file-root` mapping translates a canonical runtime filesystem root to an artifact-relative prefix. A `url-prefix` mapping does the same for one exact HTTP(S) origin and path prefix. Mappings cannot add CDP origins, broaden Electron roots, read files, or authorize source-map access; they are caller-declared inference inputs applied only to already-authorized locations. The one-shot CLI accepts either a JSON file path or the same JSON inline. A file avoids the operating system's command-line size limit for realistic Evidence records: ```bash rea reconcile-javascript-runtime reconciliation-input.json --json ``` For a repeatable local check from operator-provided paths, build first and run: ```bash npm run verify:javascript-runtime -- \ --application /absolute/path/to/app \ --cache /absolute/path/to/cache \ --runtime-evidence /absolute/path/to/electron-evidence.json \ --mapping '{"layer":1,"kind":"file-root","root":"/runtime/cache","artifact_prefix":""}' ``` The verifier analyzes the supplied static paths under a temporary in-process permission policy, reads bounded Evidence JSON files, and prints graph IDs, evidence IDs, paths, digests, counts, reasons, and coverage. It does not print captured source text. `--source-map-read-approved` remains a distinct explicit approval. ## Matching rules Runtime targets, frames, scripts, and workers become capture-scoped graph nodes. REA evaluates compatible static candidates conservatively: 1. An approved captured-source SHA-256 plus one matching mapped location yields a content-and-location match. 2. One unique exact content digest can match even when no location mapping is available. Whole-asset digests and reconstructed module-factory source digests remain distinguishable in the reported basis. 3. Without captured bytes, one unique mapped artifact path can produce a medium-confidence location match. 4. Multiple candidates remain `ambiguous`; no `observed_as` edge is emitted. `candidate_static_count` reports the full qualified layer/node count while `candidate_static_nodes` retains a deterministic bounded prefix. 5. If captured bytes disagree with the static candidate at the mapped path, the result is an explicit mismatch. A path never overrides a digest disagreement. 6. Missing authorization mappings, incomplete input coverage, and output limits remain unknown or truncated rather than becoming absence claims. Every successful cross-layer `observed_as` edge has `authority: cross-layer-reconciliation` and `state: inferred`. The underlying artifact/AST observations and passive-CDP observations remain unchanged and retain their own Evidence links. ## Loaded, resident, and not observed Static JavaScript assets, chunks, and modules receive a separate load-state classification: - `loaded` means an accepted runtime script correspondence was found, using exact bytes or one unique mapped location; - `resident-in-loaded-asset` means a containing asset was observed, but the embedded module was not independently observed or shown to execute; - `not-observed-in-capture` means the entity did not appear in the complete bounded captures supplied to this call and its artifact path falls beneath an exercised automatic or operator-declared mapping prefix; - `unknown` covers incomplete captures, layers outside runtime scope, and unresolved correspondence. Nodes outside a mapped artifact prefix stay unknown even when another prefix in the same static layer was observed. None of these states proves feature execution, initialization order, reachability, or causality. In particular, `not-observed-in-capture` never means globally unloaded. ## Frames, workers, and source maps Passive inspection retains the execution-context frame ID supplied by CDP for each accepted script. Electron captures also inventory authorized worker, service-worker, and shared-worker targets, including bounded opener-target and parent-frame relationships. These fields improve attribution while preserving the original exact-origin or canonical-root filter. V8 Inspector observations expose execution-context IDs but no authenticated frame relationship, so their scripts attach to the exact runtime target in the combined graph. They never supply source bytes, require/import caller edges, EventEmitter activity, Electron IPC, or script-unload evidence. A unique authorized file or URL location can still correlate script presence with a static asset, but it does not prove module initialization or feature execution. Source-map declarations and approved original-source reads stay under static source-map authority. They are reported in `source_map_authority` but never used as primary runtime byte matches. A source name or `sourcesContent` digest is not silently equated with the generated bytes observed by CDP. ## Bounds and determinism Inputs allow up to eight static layers and 32 passive captures. Default output bounds retain 10,000 runtime entities, 20,000 reconciliation records, and 20,000 static load states; each caller-visible maximum is 50,000. At least one target node per capture must fit. The combined graph also preserves the JAG v1 caps of 1,000 roots, 100,000 nodes, 200,000 edges, and 64 observations per node. Reaching a limit reports exact omitted counts for runtime entities, reconciliation items, static load states, and merged graph items, plus `coverage.status: truncated`. Layers, captures, nodes, edges, matches, and evidence links are canonically ordered. Repeating the same verified Evidence, mappings, and limits produces the same reconciliation, graph, and Evidence identifiers. ## Non-goals Reconciliation does not attach to CDP, fetch scripts or source maps, execute JavaScript, invoke Electron IPC, inspect native add-ons, infer arbitrary URL rewrites, or search the filesystem. It does not replace the older `correlate_static_and_runtime` investigation tool: that tool records explicit cross-version static/runtime comparison hypotheses, while this operation maps JavaScript runtime instances to static application-graph entities.