# 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. Runtime entity, reconciliation item, and static load-state projections have caller-visible limits and report omitted counts when reached. The merged application graph retains all selected roots, nodes, edges, and observations from those inputs; it adds no second aggregate prefix cap. Reaching an input projection limit reports exact omitted counts and `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.