* feat(javascript)!: require the runtime parse-failure count and active Electron execution paths The V8 Inspector projection always writes scripts.parse_failed_total and the active Electron service always commits parameters.resolved_paths, so both are now required. Runtime reconciliation reads the admitted execution paths only and no longer falls back to request-spelled paths in parameters, and checks the observed executable path against them on every capture. JavaScriptStaticAnalysis.routes and module_runtime keep their omission, which current producers still make (a checkpoint that cannot retain route facts; no recovered factory runtime); their comments now say so instead of naming historical analyses. BREAKING CHANGE: JavaScript runtime observations without scripts.parse_failed_total, and active Electron Evidence without parameters.resolved_paths, are refused as malformed; recreate the observation. * test(javascript): give the shared Node reconciliation fixture the required parse-failure count * feat(browser)!: require browser observation facts their producers always write (#10991) * feat(browser)!: require browser observation facts their producers always write The source-map fetcher always writes effective_url (string or null), the web bundle analyzer always writes schema_property_names_coverage, and the CDP storage fingerprinter always marks IndexedDB schema fingerprints with projection_version 2. Each is now required. The IndexedDB marker is tied to its scope by a discriminated union and derived from the scope in the producer, so compare_web_captures no longer carries the store-only projection branch. response_identity and the WebMCP consequential hint keep their omission, which current producers still make (a body not fully read; an invalid annotation); the guide no longer attributes it to historical captures. BREAKING CHANGE: source-map items without effective_url, WebMCP declarations without schema_property_names_coverage, and IndexedDB schema fingerprints without projection_version are refused as malformed; recreate the capture. * feat(managed)!: refuse members beside a null signature resolution (#10992) * feat(managed)!: refuse members beside a null signature resolution signature_resolution is null only when member decoding exceeded capacity, and the capacity-recovery producer then examines no members. The managed member inspection schema now enforces that: a null resolution with any field, method, member reference, call edge or field access is malformed. With that rule, every admitted inspection with members attests type-name resolution, so the raw-digest fallback is unreachable and is deleted: comparableSides, hasSignatureResolution, the comparison's signatureResolutionExamined flag and the "does not attest" limitation. The shared workflow example that carried resolved digests beside a null attestation now attests resolution. BREAKING CHANGE: managed member Evidence with a null signature_resolution and any examined member is refused as malformed; recreate the observation. * docs: describe historical Evidence by what the format revision now refuses (#10993) SQLite worker_timeout_ms is required, so the SQLite guide no longer reads a missing value as unknown settings. The IL2CPP, ESP image and process capture guides now say that bundles exported without evidence_format are refused, while a standalone record from an earlier release is still read with the stated omission semantics (records carry no format marker yet). The route inventory guide describes a parent without route_inventory by its meaning rather than by its age. * refactor(javascript): require static analysis coverage from the JavaScript worker (#11001) * refactor(javascript): require static analysis coverage from the JavaScript worker Both JavaScript static producers always write analysis_coverage: the analyzer measures it on every parsed source and the failed-parse result carries an unexamined coverage. The worker schema and the static analysis type therefore require it, the preload-discovery checkpoint copies it unconditionally, and ElectronBoundaryAnalysis reads Electron applicability and examination limits from it alone. The fallback that re-derived Electron use from semantic module links and retained references for analyses without coverage is deleted, as are the graph and builder branches for a missing coverage. Retained Evidence graph observations are unchanged: the analysis view still counts a stored JavaScript observation without analysis_coverage as unmeasured, since standalone records carry no format marker yet. The worker runs from the same build as its parent, so no external caller sees the stricter reply schema. * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts (#11002) * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts Each field is written by its only producer on every capture: - The CDP storage capture always writes content_fingerprints, fingerprint_algorithm and fingerprints_complete, so their schema defaults are removed. - The CDP Link header projection always writes context_url and context_scope, so they are required. - The source-map fetcher writes source_index and declaration_index on every mapping row, so they are required. - The fetcher judges a map invalid only after reading its complete body. A separate invalidSourceMapItem builder now takes the response identity as a required argument, and the schema's invalid member requires response_identity; fetch_failed keeps it optional because those rows can come from a body that was not fully read. The browser and source-location guides no longer describe these fields as optional for older saved captures. BREAKING CHANGE: page inspections without the storage fingerprint fields or Link context fields, source-map mapping rows without their indexes, and invalid source-map items without response_identity are refused as malformed; recreate the capture. * test(browser): keep source-omission coverage on a still-defaulted field and refuse a missing fingerprint algorithm * feat(browser)!: require web-bundle target origin, inspection producer facts, scenario redirect state and exclusion kind (#11014) feat(browser)!: require web-bundle target origin, page inspection producer facts, scenario redirect state and exclusion kind Each field is written by its only producer on every record: - buildCaptureObservation always writes capture.target_origin (the validated origin or null), so analyze_web_bundle Evidence and both web-bundle view results require it; the view's conditional spread is gone. - The CDP page capture always writes accessibility node states, script frame_id (null when unattributed) and worker opener_target_id and parent_frame_id, so their schema defaults are removed. - PlaywrightScenarioNetwork writes redirected_from_transaction_state exactly when the predecessor ID is null, so request events now require it there and still refuse it on linked events. - The reference-source importer writes entry_kind on every exclusion (unknown when the kind was not observed), so it is required. The browser scenario contract and CLI guide no longer describe older captures or exclusions without these fields. BREAKING CHANGE: web-bundle analyses without capture.target_origin, page inspections without these script, accessibility or worker fields, scenario network events with a null predecessor and no redirect state, and reference source graphs whose exclusions lack entry_kind are refused as malformed; recreate the capture or re-import the source.
11 KiB
Static JavaScript route inventory
analyze_javascript_application and analyze_web_bundle retain a shared
route_inventory alongside their existing graph and endpoint observations.
The inventory answers which route patterns the supplied code suggests, where
each pattern came from, and which parts remain unknown. It never requests a
route, executes scripts, expands a sitemap, or establishes reachability.
Select a compact view in either MCP analysis call:
{
"detail": "summary",
"view": {
"kind": "javascript-routes",
"collection": "routes",
"where": { "path_prefix": "/reports" },
"fields": ["path", "classification", "confidence"],
"limit": 20
}
}
Keep the original analysis inputs in that call. For the CLI, pass the same
selection as --view '<JSON>' --detail summary --evidence_output routes.json.
The complete Evidence bundle is written without overwriting existing files.
Unselected delivery retains the existing complete result. A web-bundle summary
requires an explicit route or web-bundle view; application summaries also support the existing
general summary when view is omitted.
Use the returned normalized_result.parent_evidence_id with
inspect_analysis_view on the same connection. The CLI's exported bundle can be
reopened with inspect-evidence-bundle; its records contain the complete
Evidence. inspect_analysis_view's evidence-file source accepts either one
Evidence record or an exported bundle with the selected evidence_id.
Views do not reopen source files or
reconnect to a browser. A parent without route_inventory is unmeasured,
rather than an empty route set.
Page captured endpoint observations and inferences
For analyze_web_bundle, select detail: "summary" and
view: {kind: "web-bundle", collection: "endpoints", limit: 32}. The CLI
accepts the same JSON through --view, with --detail summary and
--evidence_output bundle.json. Query the returned parent with
inspect_analysis_view to read endpoints, inferences, or summary without
recapturing the page or repeating JavaScript analysis.
Both row collections accept exact indices, values, script_keys, fields,
offset, and limit; endpoints also accept mechanisms, and inferences accept
kinds. Filters combine with AND, and an explicit empty selector matches no
rows. Every row retains its source_index in the original collection, including
when other fields are omitted. This identity is scoped to the parent Evidence
and collection. Original ordering and separate occurrences of duplicate values
are preserved; request endpoint location or inference basis for source details.
Follow coverage.next_offset until coverage.exhausted; those fields describe
the selected rows, independently of producer completeness. Each response also
preserves structured source_unknowns, including affected_script_keys, so a
filtered or value-only page cannot hide a source gap. The summary's
limitation_count counts distinct parent and report limitations before display
bounding. An endpoint_candidate remains an inference, with its original
confidence and basis, and does not prove a backend endpoint or reachability.
Pages obey the shared 1 MiB projection budget; MCP transport applies its own
wire-size guard. A byte-limited page returns a continuation; an indivisible
oversized record or metadata returns a typed resource error. Select fewer
fields or retrieve the complete retained parent through get_evidence_bundle
(detail: "records" with its evidence_id), export_evidence_bundle, or the
CLI's exported bundle. Full Evidence is never
silently truncated.
Collections are summary, routes, occurrences, sources, and unknowns.
All row collections support exact batch where.ids, field selection, offset,
and limit. An explicit empty filter array matches nothing. Routes also support
exact paths, literal path_prefix, classifications, mechanisms, and
min_confidence; occurrences support route_ids, source_ids, and mechanisms;
sources support keys and statuses; unknowns support source_ids and kinds.
Follow coverage.next_offset until coverage.exhausted; a page may stop early
at the 1 MiB serialized view budget. Oversized indivisible facts return a
resource error carrying the retained parent Evidence ID.
Pattern IDs bind the exact path. Source IDs bind the source key, path, original
URL, content digest, container digest, and any retained Next source applicability
context (including the owning package digest). Occurrences identify a detector mechanism at a source location; one location
may support multiple mechanisms. source_count counts distinct sources. Lookup IDs use 128 bits of SHA-256;
full content and inventory digests remain SHA-256. Field selection always keeps
row identity and necessary provenance. The page's deduplicated sources table
contains the source descriptors referenced by returned rows. Retrieve all
occurrences by route ID when independent supporting evidence matters. Source
ranges use one-based lines and zero-based UTF-16 columns with exclusive ends;
filename-only discoveries have no invented AST range.
The shared parser handles literal router calls, nested route objects, typed
_$ trees with explicitly inferred property-name fallbacks, Next App Router
page paths, and navigation targets. It follows stable lexical bindings and
keeps unresolved parents, mutations, spreads, and dynamic fields explicit.
Index-route flags use the same value-at-read boundary as path fields: erased
type wrappers and initialized stable boolean aliases preserve true/false;
uninitialized or unresolved flags retain an interpretation unknown instead of
silently disappearing.
A selected route-builder root owns its configuration even when mutation prevents
trusting its value. Ordinary wrapper keys do not become route ancestors. Missing
outer ancestors of unbound typed subtrees remain unknown rather than invented.
Generic Next runtime path constants require a top-level application segment
supported by structural or navigation candidates across the supplied sources.
This limits framework filesystem noise, while leaving unsupported candidates
unknown. The parser shares the existing AST traversal and lexical index.
Literal fragments of computed expressions, module references, and page-shaped paths owned by Next interpretation do not also become generic route constants. Selected getter results retain the shared semantic owner's allocation identity; finite selections can claim their query data, while widened or cyclic selections keep an unknown in the interpretation that requested them.
Next page conversion receives an explicit source context. For local source files,
the shared JSON owner first establishes a declared next dependency in the
nearest owning package. Inventoried directories then select that package's app
before src/app, following Next's root selection.
Only files beneath the selected directory supply source-page support. Default
.next/static/chunks/app output receives a separate compiled-directory context
from the same package owner; custom build directories remain unmodeled. Pages Router
files, unrelated components, and nested packages do not inherit that root merely
because their paths contain app. Missing package/framework evidence remains an
interpretation unknown for page-shaped source paths. Each page-shaped source retains its
next_app_context and package identity so this derivation remains inspectable.
Captured script URLs use the /_next/static/chunks/app/ asset boundary, independently
of local package evidence. Source literals use recognized Next runtime context;
imports, exports, and direct call arguments do not themselves declare pages.
The parser completes its runtime-marker scan before interpreting retained module
literals, so marker placement does not change the result. A matching filename
suffix alone cannot establish App Router ownership.
Next dynamic segments
map to :id, :slug+, or :slug*; groups and parallel slots do not contribute
URL segments. Intercepted routes remain unresolved. A prefix before /_next/
is an inferred routing base: assetPrefix
can differ from the routing base. Every affected occurrence keeps
unprefixed_path, inferred_base_path, and low confidence. system classification
is explicitly a path-name heuristic; page uses page-file or structured/typed configuration support. Name-only
route/addRoute calls remain unknown because they can also register server APIs.
Next page-source segments keep their filename spelling when converted to route
patterns. Next's page-path conversion
removes page extensions and the index tail without URI-decoding segments, so
ordinary percent sequences are not decoded: %61 and a remain separate
candidates and a literal % is retained. Its App pathname normalizer
specifically applies the underscore normalizer,
which maps %5F to _; private-folder checks apply to the source spelling
before that escape is mapped. When classifying a chunk URL, REA reads its
pathname, then applies these same Next-specific rules. This is static source-path
interpretation, not browser request-path decoding or reachability.
Known capture omissions remain inline in summary.reported_capture_omissions
and queryable as unknowns of kind capture-omission. Each keeps a stable gap ID,
its script-record/script-source unit, and the reported count (including null
for unknown). They do not invent missing script identities or source ranges.
Counts describe deduplicated patterns in the provided code sources. They are
not a denominator for complete application or capture coverage. In particular,
server-only, lazy, inaccessible, or unselected sources may be missing.
coverage.application_routes always remains unknown; parsing and candidate
enumeration have their own completeness. Static work and fact admission share
the existing 8 MiB per-source transfer ceiling, and the root inventory has an
8 MiB admission budget. Exhaustion preserves a prefix with explicit capacity;
the serialization owner also admits route facts within the actual space left by
legacy facts. result-bytes capacity preserves an earlier work-capacity reason;
if even that envelope cannot fit, the optional route facet remains unmeasured.
These are accounting bounds, not a claim that total process memory is 8 MiB.
Projection only reduces delivery, not analysis work. Retained immutable Evidence can reuse validated tables through a weak cache with the snapshot's lifetime; subject identity is checked on every query. No live state or source content is cached as current. Use existing source selection and resource controls when they match the investigation, keeping their partial coverage visible.