mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 09:52:27 +00:00
fadfdf13e617fa9a6025b6180459a13844f2a9ca
148
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ab84ba6839 |
fix(process)!: retain inspection cancellation and cleanup ownership (#10113)
* fix(process): preserve producer-owned inspection cancellation Prototype the explicit inspection origin and retained file/batch owner protocol. Downstream adapter migration and lease binding remain required before integration. * fix(process): type inspection ownership handoffs precisely * fix(process): retain plain inspection preparation cancellation * fix(process): retain explicit inspection cleanup and cancellation facts * fix(process): require explicit inspection facts and cleanup scope * refactor(process): remove redundant cleanup forwarding wrapper * fix(firmware): retain inspection cancellation and cleanup ownership * fix(wakaru): retain typed inspection outcomes and caller scope * fix(ghidra): preserve inspection facts and launch cleanup scope * fix(providers): preserve typed process inspection outcomes * refactor(process): remove obsolete inspection cancellation re-export * fix(native): preserve inspection preparation cleanup and cancellation * fix(registration): retain typed inspection cleanup during Git discovery * fix(process): preserve inspection deadline origin in adapter handoff * fix(process): consume the canonical inspection selector in binding * fix(native): preserve inspection deadlines and cleanup retry completion * test(process): narrow the retained Darwin preparation owner * fix(providers): preserve preparation ownership and timeout policy Narrow preparation facts through their canonical owner, preserve actual cleanup capabilities and recorded cancellation, and keep enclosing command deadlines authoritative. Retain raw inspection records through Java refusal and configuration projections without changing availability fallback policy. * refactor(process): use one inspection failure type owner * fix(providers): retain recorded secondary failures when rebinding * fix(ghidra): preserve normalized inspection facts through public projection * fix(process): normalize native process listing cancellation * docs(development): clarify failure provenance and cleanup verification * fix(process): preserve direct inspection cancellation facts * fix(process): retain inspection owners through termination * fix(process): preserve command inspection cleanup provenance * fix(desktop): preserve inspection facts after cleanup retry * refactor(process)!: migrate desktop capture with inspection producers * fix(desktop)!: preserve capture failure origins and cleanup owners (#10115) * fix(desktop): preserve capture failure origins and cleanup * fix(desktop): type keyring cleanup cancellation * fix(kuna)!: retain copy cleanup before retiring workspaces (#10114) * fix(kuna): own copy cancellation and descriptor cleanup * fix(kuna): close copy descriptors before workspace removal * test(kuna): type copy lifecycle gates for project library * docs(kuna): explain retained copy-file cleanup and staging ownership * docs(kuna): separate cache publication, integrity and cleanup guidance * fix(desktop): retain sampling inspection owners before release * fix(process): preserve capture file read cancellation origin * fix(process): retain capture inspection cancellation and cleanup owners * fix(process): retain sampling inspection failures in capture scope * fix(process): retain inspection failures through mandatory cleanup * fix(process): distinguish sampler shutdown from capture cancellation * fix(browser): retain startup EOF before later cancellation * fix(process): bind capture inspection cleanup to the owning run * test(process): migrate cancellation fixtures to typed owners Record explicit preparation and command cancellation facts, retain exact opaque reasons and physical causes, and guard the mocked version probe from native preparation. Keep the live Wakaru command control while adding a recording equivalent for bounded source verification. * fix(process): own sampling reads and settle inspection peers * fix(errors): retain authored recovery through cleanup composition * fix(process): retain all sampling inspection leaves for final cleanup * test(browser): report recording cleanup signal outcome * fix(process): keep inspection error context out of implicit JSON * fix(desktop): retain normalized sampling cleanup ownership * test(process): assert tagged startup cancellation |
||
|
|
7aca4cef64 |
feat(audit): report what a shipped app exposes to static analysis (#8525)
* feat(audit): report what a shipped app exposes to static analysis
Adds `audit_release_exposure` and `rea audit-release-exposure` to report
source maps, Electron fuse implications, extractable payloads, debug
information, build metadata, and credential markers. Checks carry stable
IDs, observations, statuses, and fixed remediation, while incomplete and
unassessed checks remain visible without implying a security verdict.
Credential findings include only rule IDs and locations. The CLI
supports `--fail_on` severity thresholds and exits 3 when an exposed
check meets the threshold.
* fix(audit): keep incomplete coverage unknown across text, fuses, Go flags and cancellation
Probe files with unrecognized names as text, keep undecided fuse slices
unknown, forward opaque container coverage, read paths from Go build flags,
and compare inventoried digests before accepting owner facts.
Keep typed cleanup failures and attach the partial report when a later owner
is cancelled. Pin the verifier's @electron/fuses version and move the tests
to the named contract family.
* fix(audit): match package members by source spelling and close remaining coverage gaps
Reopen package members by their source spelling and keep caller path
traversal in directory reads. Parse quoted and attached Go build flags, bind a
native image fuse read to its own digest, and keep reader resources and the
audit's partial report when cleanup or cancellation combine failures.
* fix(release-exposure): bind package members by ordinal and follow named map references
Package members were matched to container entries by sourcePath, which is
not unique in a PyInstaller executable, through a queue that only moved when
a member was reopened. Bind by container-relative path and duplicate ordinal,
the numbering inventory uses, so read order cannot change which bytes a
member gets.
A sourceMappingURL naming a file without a map extension was ignored. Local
targets are now examined as maps whatever their name, and a target already
scanned as plain text leaves coverage unknown.
* fix(release-exposure): match data: source map scheme case-insensitively
URL schemes are case-insensitive, so an inline declaration such as
//# sourceMappingURL=DATA:application/json;base64,... was routed to the
local-reference path, which ignores scheme URLs. Its embedded sources were
silently dropped and source_map_sources reported not_observed.
* fix(release-exposure): normalize declared map targets and count unreached ones
A sourceMappingURL that decodes to a decomposed name (cafe%CC%81.json)
never matched the inventoried member, whose logical path is NFC, so the
map was scanned as ordinary text and its sourcesContent went uncounted.
Map-target lookups now use an NFC key on both the record and lookup
side; the declared URL is left as written.
A declared map target that is never reached is now counted as a skipped
map, so the source-map checks read as unknown coverage instead of
not_observed.
* fix(release-exposure): recover indexed leaves after any map format failure
An indexed map whose one leaf has malformed mappings (such as AA) threw a
format failure that only recovered leaves for unsupported sections, so a
valid sibling leaf with sourcesContent was dropped and
javascript.source_map_sources read unknown instead of exposed. Leaves are
now recovered for any format failure, with the envelope parse guarded so
invalid JSON still falls through to the unparsed count.
A nested package that inventory recognized but did not expand was probed
as a plain binary and left the source-map checks at not_observed. It now
marks coverage unknown and records a limitation.
Reader tests assert the javascript.source_map_sources status for the NFC
map-name cases as well.
* fix(release-exposure): count an unexpanded nested package as a readable member
An unencrypted nested package that inventory recognized but did not
expand is still a member its parent package already read. Count it as
readable so packaging.extractable_payload reports exposed, while its
own contents keep coverage unknown.
* fix(release-exposure): bound the indexed leaf fallback by decoder limits
The fallback walk after a map format failure expanded every section and
built a full ancestor path per leaf, so a map refused for nesting depth
could still allocate far past the decoder budgets. Walk only to the
64-level section depth and the shared record budget, keeping leaf maps
without materializing section paths.
* fix(release-exposure): collect UNC roots from Go flag paths
A flag such as -I\\buildhost\sdk\include matched none of the path roots
in GO_FLAG_PATH, so a network path that was the only one in complete
build info left go.build_paths at not_observed. Accept \\host\share
roots alongside the slash-rooted, dot-relative and drive-letter forms.
* fix(release-exposure): keep Electron undecided without positive proof
The desktop owner names Electron only from an ASAR layout, so an asar: false
build has no candidate. A complete scan with no candidate was reported as
not_electron, which outranks unresolved and safe fuse outcomes and hid them
as not_applicable.
Leave the family unknown unless the fuse holder rules Electron out: an app
bundle with no Electron Framework, or a directory with complete coverage
whose native images were all read and hold no sentinel. A directory with no
native image is not proof, so its fuse checks now report unknown.
* fix(release-exposure): decode wide text members before scanning
A member's kind bypassed the NUL guard, so a UTF-16 plist was decoded as
UTF-8, matched nothing and still counted as scanned. A directory holding
only that member reported text.credential_markers as not_observed.
Decode by byte order mark at one boundary instead. UTF-16 is scanned in
either byte order, and inline maps read the same text. UTF-32 and NULs no
mark explains count as skipped, whatever the member's kind. A binary
plist keeps its raw scan. Unnamed members with a mark now reach the
scanner, and the plist decoder shares the same mark detection.
* fix(release-exposure): follow file: URL source map declarations
The scheme guard in noteLocalMapReference returned on every URL scheme, so
a declaration such as file:///release/debug.json was dropped with the remote
ones. A member without a .map name was then scanned as ordinary text and
javascript.source_map_sources reported not_observed.
Convert file: URLs with fileURLToPath and record them in mapTargets through
the same step as relative declarations. A target that is never reached, or
that was already scanned as text, counts as skipped, and so does a malformed
file: URL. A file: URL names one absolute location, so a .map target outside
the inventory stays unassessed rather than being trusted by its name. Remote
schemes stay ignored.
* fix(release-exposure): match backslash-relative Go flag paths
GO_FLAG_PATH accepted dot-relative roots only with a forward slash, so
`-I..\sdk\include` and `-I.\sdk` produced no path and go.build_paths came
back not_observed. Accept either separator after the dots.
The CLI acceptance test now expects unknown for electron.run_as_node on a
directory with no native images, matching the service.
* fix(release-exposure): keep fuses unknown on incomplete inventory
A directory inventory that stops at an acquisition limit never reports
the images it did not reach, so the native image sample has no omission
and safe fuses on an included helper settled to not_observed even though
scan coverage was unknown.
Treat unknown coverage like a truncated sample until the Electron
executable is accounted for. A selected native file is that executable,
so it keeps its decided fuse result.
* fix(release-exposure): decode binary plists before scanning
A binary plist stores each string as ASCII or UTF-16BE. Scanning the raw
bytes as UTF-8 missed any string the encoder kept in UTF-16, such as one
with a non-ASCII character, and still counted the member as fully
scanned, so text.credential_markers read not_observed.
Decode through the plist owner and scan its strings, dictionary keys and
data. A plist that cannot be decoded keeps its raw bytes in the scan and
counts as skipped, so coverage stays unknown.
* fix(release-exposure): keep UTF-8 members that hold a NUL
Any NUL in a member's first 512 bytes made the decoder give up, so a script
with a literal NUL in a string never reached the credential or inline-map
checks. An exposed marker in it read as unknown, and --fail_on high exited 0.
Validity alone cannot tell wide text from UTF-8, since ASCII in UTF-16 is
valid UTF-8. Treat a header that is an eighth or more NUL bytes as wide text
and anything not UTF-8 as undecoded, and scan the rest.
The docs now separate BOM-marked UTF-16, which is scanned, from wide text
with no byte order mark, which is not.
* fix(audit): scan every string a binary plist stores
The plist scan read only the decoded value, which drops objects the root no
longer references and entries a later duplicate key replaced. Those bytes
still ship, but the audit marked the scan complete, so a credential stored
there read as not observed and --fail_on high exited 0.
Read strings, keys and data from the object table instead. A stored object
that cannot be read leaves the member unassessed, and a total byte budget
bounds table entries that overlap to repeat the same text.
* fix(audit): keep packaged native images from ruling out Electron
The applicability check only looked at the "native images" omission. An
Electron executable inside a compressed .NET or PyInstaller member is recorded
under "packaged native images", so a directory whose on-disk hosts had no fuse
sentinel read as not Electron and all four fuse checks as not applicable.
Treat that omission as an unread image too.
* fix(audit): keep readable plist text when one object is unreadable
Throwing on one unreadable stored object discarded every string already
decoded, so a UTF-16BE credential beside a truncated unused object was lost:
the raw bytes that replaced it cannot match NUL-separated text.
Return the decoded text with complete false instead, and keep the raw bytes
in the scan beside it so ASCII in the unread object is still seen. The member
stays unassessed. Text past the budget ends the same way.
* fix(audit): read escaped inline maps and extensionless SEA entries
A data URL may percent-escape its base64 payload, so a map such as one padded
with %3D did not decode and the audit counted no embedded source map. Decode
the escapes before reading the base64.
A directory walk classed a SEA entry by its code path, so a main script whose
code path names no script was never scanned as JavaScript and its inline map
went unseen. Class it by the role the SEA metadata gives it.
* fix(audit): check plist text against the budget before decoding it
decodeBinaryPlistText decoded each stored object before comparing its size
with the remaining budget, and it keeps going after an object is rejected so
later text is still read. A plist under the input limit could repeat a large
range through overlapping table entries and force gigabytes of decoding that
the audit then discarded.
Separate finding a stored payload from decoding it, so a range past the
remaining budget is rejected without allocating its text. Earlier text and
the incomplete result stay as they were.
* fix(audit): count a packaged PE with an unread header as a native image
A package member whose PE signature lies beyond the 4 KiB probe recorded only
a PDB failure. The image was neither read nor listed under packaged native
images, so a directory whose on-disk hosts had no fuse sentinel read as not
Electron and all four fuse checks as not applicable.
Count it as a packaged native image, the omission that keeps the question
open, and keep probing it for text as before.
* fix(audit): keep cleanup-incomplete errors from composed readers
A desktop, fuse, Go or Rust failure became a string on that check, so an
error with unfinished cleanup lost its resources and live bindings while the
audit reported success, and the MCP handler does not close the service after
each request.
Treat unfinished cleanup like cancellation: stop the remaining owners and
return the error with the partial audit. When the owner attached its own
partial, keep the error and replace the partial, so cleanup stays attributed.
* fix(audit): keep safe fuses unknown past a packaged native image
The fuse check counted sampled-out images as possibly unread but not native
images inside a package. A complete directory scan with a safe-fuse image on
disk, no ASAR hint, and an unopened packaged image reported the four Electron
checks as not_observed, although the Electron executable could be that image.
The fuse check, the Go and Rust checks, and the Electron rule-out each decided
this for themselves and had drifted apart. Move the decision to one domain
predicate, nativeImagesMayBeUnread, and use it in all three. A hinted
executable that was read still settles the check.
* fix(audit): settle fuses only on an identified host, and read Bun and HTML maps
A retained helper set electron_executable_included because the rank marks
every .exe or extensionless sibling of resources/app.asar. With more than four
siblings, or an inventory that stopped early, safe fuses on a helper reported
not_observed while the host went unread. Rank stays a sampling hint. The check
now settles only on an executable named as the host, or when inventory was
complete and every executable that could be the host was sampled.
A Bun sourcemap region is named .bunmap, so its role was lost and a complete
audit reported no source maps. Carry the region role from the reader's metadata
into the member view, in the expanded and unexpanded paths, and treat it as a
JavaScript map so an unparsable region stays unresolved, not a debug companion.
An HTML member was scanned as text but its inline scripts were never checked
for source maps. The HTML owner now returns each body, the reader examines it
like a script file, and bodies past the owner's limit count as skipped.
* fix(audit): charge map reads to the count before opening the member
An oversized or unreadable .map returned before readSourceMap counted it, so
the allowance of 32 never ran out. An unexpanded .NET or PyInstaller package
could then decompress every listed map member, about 1 MiB each, up to the
4,096 entry cap.
The count bounds reads, so examineMap now reserves the slot before it opens the
member. A map past the count is skipped unopened, and a linker map past it is
still settled from its bounded prefix. An inline data: map is already in memory
and keeps its charge at the point it is parsed.
* fix(audit): examine scripts HTML loads whatever they are called
isJavaScriptMember knows a script by its suffix or an assigned kind, and the
reader dropped the script references the HTML owner parses. An extensionless
main loaded by <script src="main"> was scanned as ordinary text, so a complete
inventory reported javascript.source_map_sources not_observed with shipped
sources in its inline map.
The reader now resolves each JavaScript script reference against the page and
its base href, and a local target without a JavaScript name is examined as a
script when reached. A target read before its HTML file, never reached, or not
placeable on disk counts as a skipped map, so the check stays unknown.
* fix(audit): charge sibling map reads to the map count
Every generic .map beside a selected file got a full 1 MiB read and a
parse, with no cumulative bound, so the 4,096-entry listing allowed about
4 GiB of reading for one small selection.
Move the slot rule into chargeMapRead, which examineMap and sibling
classification now share. Past the count a sibling reads only the header:
a linker map is still identified, and one that may be a source map stays
a skipped companion.
* fix(audit): report cleanup failures raised by member reads
A close failure during an embedded-package probe, member read or inventory
reaches the shared read filter as an ordinary reader failure. The filter kept
only cancellation and integrity, so the member became a skipped read, inspect
succeeded, and the retained descriptor was reported nowhere. MCP does not close
the service after each request, so no caller saw it.
Propagate any failure that carries cleanup, whatever its reason, so it reaches
releaseExposureFailure and the audit reports its retained resources.
* fix(audit): charge unsuccessful text reads to the byte allowance
An oversized, undecodable, or failed text read left textBytes unchanged, so
every member got the full per-member budget and the cumulative allowance did
not bound what a package decompressed. Count the bytes member reads produce
and charge them whatever the read yields. An oversized file on disk still
costs only its probe.
* fix(audit): bound the paths kept for HTML script targets
A base href is copied into every script target it resolves, so a page under
the text member allowance could retain hundreds of megabytes of paths. Charge
each new target's resolved path to a byte allowance and leave targets past it
unassessed.
* fix(audit): keep examining a page loaded as a script as HTML
A script element naming an .html member promoted that member to a
script, and the text pass then chose one reading. The page's own script
elements were never read, so an inline map in it was lost and a shipped
sourcesContent went unreported.
Run the script reading and the HTML reading independently, and list the
script target allowance among the cases that leave source map coverage
undecided.
* fix(audit): detect credential markers that end in a hyphen
The Google, GitLab, and Slack rules allow a hyphen in the token but ended
on a word boundary, so a token ending in a hyphen at the rule's minimum
length was missed and the audit reported the check as not observed.
Open-ended rules now take the whole token, and the fixed-length Google
rule checks the full token alphabet after its last character.
* fix(audit): confirm FAT identity for probed package members
The package probe treated a decoded FAT table as a universal Mach-O. A
JVM class past the 4 KiB probe shares the FAT magic, so its truncated
prefix decoded as a table, the member counted as an unread native image,
and Electron could not be ruled out of a complete scan.
Pass the member's declared size to the sniff and take identity from
classifyFatContainerEvidence. A member with no usable size, or with
slices past the probe, stays counted as possibly native.
* fix(audit): admit binary plists in package member probes
A package member's probe judged text by its own NUL test, which accepted
byte order marks but not the binary plist signature decodeMemberText also
reads. A PyInstaller executable shipping a binary Localizable.strings was
rejected without a scan or a skipped count, so a UTF-16BE private key
marker inside it could report not_observed.
Name the encodings that explain their own NULs in one predicate, and move
the plist fixture builders to module scope.
* fix(audit): locate Go findings only in images that retain build paths
The exposed decision required non-empty paths, but the locations took
every image whose build info read. An image with no paths was named as a
source of the leak beside the one that had them.
One predicate now decides both.
* fix(audit): keep completed findings when member cleanup fails
A descriptor close failure aborts the member scan, and the scan's state
was dropped with it, so the caller got a typed cleanup failure and no
report. Source maps already counted and credential hits already collected
were lost.
The reader now hands the service what it assembled, with coverage unknown
and a limitation saying so, alongside the failure. The service runs that
scan through its existing stopped-audit path: no later owner runs, and the
report goes on the error as its partial observation.
* fix(audit): keep coverage unknown for nested ASARs in package hosts
A member of a PyInstaller or .NET host reaches the binary probe as a
plain file. An ASAR among them has a NUL-bearing header, so the probe
dropped it with no traversal and no omission, and source map checks could
read not_observed with complete coverage.
Ask the ASAR owner's signature probe, and record a match as a nested
package that was not expanded, as inventory-classified ones already are.
* fix(audit): let native format facts outrank member names
examineMember tried the name-based text and map routes first, so a PE an
owner identified inside an ASAR, named payload.json, was read as text.
Its CodeView path and the packaged-native omission were both lost, and
native.pdb_path read not_applicable.
Route an owner-established native format to the native probe first, and
count an encrypted one as a packaged native image for the same reason.
* fix(audit): report relative paths given to compiler path flags
go.build_paths only kept rooted paths, so retained build settings like
CGO_CFLAGS=-Iprivate-sdk read not_observed even though the setting names
a directory.
Take the relative argument of a C compiler path flag, attached or in the
next field. Scope this to compiler settings, because Go's own tools use
the same letters for non-paths such as -B gobuildid and -T 0x1000.
* test(javascript): expect retained text on SVG inline scripts
The SVG test from main predates this branch's inlineScripts text field,
so each side passed alone and only their merge failed.
* fix(audit): keep an unresolved Electron host's fuses unknown
fuseCheck decided from whatever outcomes the images reported, so a host
with no fuse answer read not_observed as soon as any other image in the
directory reported safe fuses.
Pass the images named as the host into the report and leave a check
unknown when one of them has no answer for it. Other images stay free to
have no fuses, because helpers in a real Electron install have none.
* fix(audit): bound the paths kept for local source map targets
noteMapTarget kept every declared target resolved against its member's
directory, so a short URL under a long directory could retain far more
than the script's own size, with no cumulative limit.
Add the allowance noteScriptTarget already has. A target past it stays
unassessed and counts as a skipped map, and is never read.
* fix(audit): borrow the audit's scope admission for inventory
inspect holds resources.run for the whole audit, and inventoryArtifact
entered the same scope again. With failed cleanup pending from another
audit, the inner run waits for a drain that waits for the outer run.
Add inventoryArtifactInScope, which takes the caller's admission.
* fix(audit): run the exposure verifier's commands under supervision
The verifier launched npm and the CLI with raw execFile and then removed
its temporary tree, so a timed-out child could outlive the tree it was
using.
Use the shared verifier commands and close them before removing the tree.
Their exit error carries stdout on its snapshot, so the audit's exit-code
branch reads it from there.
* fix(audit): read relative -L paths and split flag arguments
The relative-path reader handled C compiler settings only, so a directory
kept through Go's own linker flag, such as -ldflags='-L private-sdk -s -w',
reported go.build_paths as not_observed.
A quoted flag and argument also reached it as one field. The separating
space stayed on the argument, which reported rooted paths twice and kept a
leading space on relative ones.
Give -ldflags its own pattern that matches only -L, so -B gobuildid and
-T 0x1000 stay ignored, and consume the separator in the flag patterns.
* fix(audit): keep embedded leaves beside schema-invalid map fields
The reader recovers independent indexed leaves only after a
SourceMapFormatFailure, but inspectSourceMap let the schema's ZodError
through. A sibling with mappings "!", a section with a bad offset or a
root with a bad field skipped recovery, so a valid leaf with
sourcesContent reported javascript.source_map_sources as unknown.
Normalize schema rejection in SourceMapFormat, which owns these parses,
so every structural failure reaches consumers as a format failure. The
message is unchanged, and the codec and web fetcher already map both
cases to the same result.
* fix(audit): keep packaged executables' own packages unknown
examinePackagedBinary counted a native image inside a package and moved
on, while only on-disk images reached the embedded-package probes. An
ASAR carrying a PyInstaller, Bun, Node SEA or .NET executable with a
source map therefore scanned complete and reported
javascript.source_map_sources as not_observed.
Run the same classifier on packaged images. The probes read carrier
offsets from a file, so the member's bytes stay in a temporary file for
the probe alone. A detected package keeps member coverage unknown, as a
nested ASAR does, and an image past one file's total byte allowance
stays unprobed and unknown. A plain native member leaves coverage intact.
* fix(audit): read an app's sampled images for fuses
A .app target sent only the bundle candidate to the fuse reader, which
resolves to the outer Electron Framework. A sidecar with RunAsNode enabled
was never read, so the check reported not_observed in the app view while
the directory view reported exposed.
Send the bundle candidate first and then the sampled native images. An
image whose digest matches the bundle's read is skipped, so the framework
is not read twice. A sidecar's safe fuses cannot settle the outer framework,
so a bundle read with no answer for a fuse keeps that check unknown.
* fix(audit): read a Node shebang as script identity
The path classifier gives an extensionless executable a resource kind,
so a script such as bin/runner with a `#!/usr/bin/env node` header was
scanned as text without its inline maps being examined or counted. A
complete inventory then reported no shipped sources for it.
The probe holds the first bytes a member reader sees, so establish the
identity there. The script keeps the usual outcomes: a map that is read
counts, and one past an allowance or undecodable stays unknown.
* fix(audit): keep linker strings out of Go build paths
Reading `-X 'main.usage=-L level'` as a library directory made
go.build_paths report `level`, so a plain string could fail an audit
under --fail_on low.
Read the optional package selector once, before the setting's first
flag, and keep the argument of -X attached to it, so a string it sets
is never scanned as another option.
* fix(audit): keep a failed probe directory removal owned
A packaged image's probe copies the member's full bytes into a temporary
directory. When removing it failed, the error became an ordinary
unreadable probe: the audit could still succeed, nothing could retry the
removal, and the client heard nothing about the leftover bytes.
Hold the directory in the reader's resource scope, so close retries it,
and report the unfinished cleanup without replacing a primary failure.
* fix(audit): keep a declared .map from reading as a linker map
A script's sourceMappingURL=assets.map was dropped because the name
already looked like a map. A malformed assets.map then settled as a
linker map, so both source-map checks read not_observed and
native.debug_companions reported an exposure the release does not ship.
Keep a generic .map name as a declared target and read it as a
JavaScript map, in either scan order, so it stays unresolved.
* test(audit): rethrow typed errors from release exposure checks
A failed Result was rewrapped in a plain Error, which dropped its type,
cause and cleanup details from the test output.
* fix(audit): match companions by member identity, not spelling
An ASAR member's location is relative, and a declared map target is
absolute, so a malformed assets.map read before z.js stayed a linker
companion. The examined-map lookup, which is normalized, then returned
early, leaving both source-map checks not_observed.
Index companions by memberLocationKey and keep each reported spelling
under it. Spellings stay distinct because symlinks can make them differ.
* fix(audit): retract only guessed linker maps on a declaration
A script declaring sourceMappingURL=symbols.pdb after the scan reached
symbols.pdb removed the shipped PDB from the companion list, because a
late declaration retracted any companion. native.debug_companions could
then read not_observed.
Keep name-identified companions in their own set, and retract only maps
that were read as non-JSON and guessed to be linker maps.
* fix(audit): record an unfollowed map link as skipped
The directory and ASAR readers do not follow links, so a symlinked
app.js.map dropped out before any map counter moved. Its target was
scanned as plain text, and both source-map checks read not_observed.
Count a link that names a map as skipped wherever entries reach the
audit, and mark it examined so a declaration does not count it twice.
* fix(audit): read relative paths in Go compiler and assembler flags
A binary built with -gcflags=-I private-sdk keeps that setting, but
relative parsing covered only C compiler settings and -ldflags, so the
directory dropped out of go.build_paths.
Give -gcflags and -asmflags their own path options, taken from what
go tool compile and go tool asm document, and strip the package selector
as -ldflags does. The assembler's -D defines a symbol, so it is not one.
* docs(audit): state the packaged image read allowance
Packaged ELF, Mach-O and PE images are read in full and copied to a
temporary file, sharing one max_file_bytes allowance, but the docs and
coverage.allowances still said only a PE gets more than a header read.
Name the allowance and the copies in docs/release-exposure.md,
RELEASE_EXPOSURE_ALLOWANCES and the max_file_bytes description.
* docs(audit): say how go.build_paths treats rooted -X values
A rooted -X value cannot be told from a file path, so the audit reports
it. State that, and why, so the rule is a contract rather than a side
effect of how flags are scanned.
* fix(audit): keep a declared sibling map out of the linker guess
When the selected file declared a sibling map, the sibling classifier
never consulted the declaration. A malformed assets.map then read as a
linker map and raised native.debug_companions.
Leave a declared sibling to the unreached-target accounting, as members
already are, so it stays an unresolved source map.
* fix(audit): keep undecodable Go and Rust metadata unknown
Unsupported meant two things: a container this reader does not handle,
and metadata the image holds in a form the reader cannot decode, such as
a compressed .dep-v0 section. Both read as not_applicable, so an image
that carries metadata reported that the check did not apply.
Mark the second case on the format failure and carry it on
AnalysisUnsupportedTargetError, so the audit records a failed read and
stays unknown. The tools' own errors and messages do not change.
* fix(audit): keep coverage unknown for a PE header past the probe
A packaged member whose PE signature lies beyond the probe prefix stayed
unclassified, so the embedded-package probe never ran and coverage stayed
complete. A map inside such an image then read as not_observed.
Record the member as an unexamined package where it is already marked as
a possible native image.
* fix(audit): read the scripts of a standalone SVG
An SVG can carry a script with an inline source map, but only .html and
.htm members reached the script owner, so such a file left every map
counter at zero and javascript.source_map_sources read not_observed.
Treat .svg as a script-bearing page. htmlArtifactReferences already
reads SVG script elements, so this adds no parsing.
* fix(audit): keep every possible host when no name picks one out
With no named Electron host, every sibling ranks alike and
electron_host_paths stayed empty, so one image's safe fuses settled the
checks even when another possible host reported none.
Keep all sampled candidates as hosts in that case, so a candidate
without fuses leaves the checks unknown.
* fix(audit): read a text-named native member by its bytes
A PE member called payload.json took the text route, so it reached no
native probe, and its CodeView path and packaged-native uncertainty were
lost.
Decide from the bytes the text read already loaded, so real text costs
no extra read and the map and text allowances stay as they were.
* fix(audit): let a map or script read identify a native member
A package lists names without formats, so a PE called payload.js.map
took the map route and never reached a native probe. Its CodeView path
was lost, and with nothing counted as failed, native.pdb_path could read
not_applicable. A PE at a declared script or map target was lost the same
way, because declaration overrode the route.
Decide from the bytes the route already read, in the map route as in the
text route, and keep the listed kind for a promoted script target. Real
text and maps cost no extra read, so those allowances are unchanged.
* fix(audit): name a symlinked sibling debug companion
Selecting an executable skipped every symlink beside it before the name
check, so an app.pdb link left no companion path and no skip count, and
native.debug_companions read not_observed. Selecting the directory
reports the same link.
Check the name first. The map branch already needs a regular file, so no
link is followed.
* fix(audit): keep map coverage unknown for a linked script
A link named app.js to an extensionless payload was skipped as a link,
and its target was read as plain text with no map directives parsed. An
inline map there left no parsed or skipped count, so
javascript.source_map_sources read not_observed. Only links with a map
name were counted.
Count a link under any name that can declare a map, the set an unread
member already uses. It stays one omission when a page or a directive
also names it. The target is still not followed.
* fix(audit): keep a declared JavaScript map beside a selected file unknown
A local sourceMappingURL with a JavaScript map name such as app.js.map
was dropped on the assumption that it would be examined as a member.
When the selection is a file, sibling .js.map files are never read, so
the declared map left javascript.source_map_sources not_observed while
the same target spelled as a file: URL left it unknown. Record every
local target so an unreached one counts as skipped.
* fix(audit): read paths a C compiler forwards to the linker
CGO flags can hand linker options through -Wl,a,b or -Xlinker a. The
compiler flag parser saw -Wl,-L,private-sdk as one field and missed the
relative library directory, so go.build_paths reported not_observed.
Split forwarded options out before reading paths and read them with the
linker's own path options (-L, -T, --library-path, --script). This also
stops -Xlinker -Bsymbolic from being read as the compiler's -B prefix.
* fix(audit): read forwarded linker options by their linker meaning
The forwarded linker flag pattern read -Ttext=0x400000 as a script path
named text=0x400000, and it ignored -I, so -Xlinker -Ilib/ld-custom.so
lost the interpreter path the compiler flag pattern found before the
split.
Exclude the -T section and segment address options (bss, data, text,
text-segment, rodata-segment, ldata-segment) and read -I and
--dynamic-linker as paths.
* fix(audit): split Go flags as Go does and read external linker flags
Go splits a flag value with quoted.Split: a field that starts with a
quote runs to the matching quote, and any other quote is a literal
character. The reader stripped every quote, so CGO_CFLAGS
-I"/home/O'Neil/include" reported /home/ONeil/include, while cc was
given the directory "/home/O'Neil/include", quotes included.
-ldflags kept -extldflags values with the Go linker flags, where only
-L counts, so -extldflags=-Lprivate-sdk reported no path. The values
are now read as the C compiler driver reads them, including -Wl, and
-Xlinker forwarding.
A package member named payload.json or payload.js.map that holds an
ASAR took the text or map route, which checked only native signatures,
so the nested archive was scanned as text and coverage read complete.
The route's own read now recognizes the ASAR signature as well, and the
nested package leaves coverage unknown.
* fix(audit): keep a named script beside a selected HTML file unknown
A script element whose target had a JavaScript name such as app.js was
dropped on the assumption that it would be examined as a member. When
the selection is an HTML file, sibling scripts are never read, so a
sibling holding an inline map left javascript.source_map_sources
not_observed while the same target named app left it unknown. Record
every local script target so an unreached one counts as skipped.
* fix(audit): read a retained -pgo setting as one profile path
`-pgo file` names a single profile, and under -trimpath Go keeps only
its file name, so the flag readers dropped values such as
`private-training.pgo` and split paths with spaces or commas. Report
the value whole, skipping `auto` and `off`.
* fix(audit): read -extldflags paths as the external linker splits them
With -ldflags set to -extldflags '-L "/srv/private sdk"', the outer
flag reader could not match the path behind the inner quote, and the
external reader kept only relative paths, so go.build_paths read
not_observed. Read each -extldflags value once, as go tool link splits
it with quoted.Split, and collect rooted and relative paths from those
same arguments. The rest of the setting is read as before.
* fix(audit): read the Go linker's other path options
go.build_paths read only -L as a Go linker path option, so a retained
-ldflags='-tmpdir=private-obj -s -w' reported no path and --fail_on low
missed the directory.
Read every option `go tool link -h` documents as taking a directory,
path or file: -I, -L, -benchmarkprofile, -capturehostobjs, -cpuprofile,
-fipso, -importcfg, -memprofile, -o, -r and -tmpdir. -extld, -extar and
-libgcc name a program or `none`, so only their rooted values count.
* fix(audit): keep a quoted Go argument whole
goFields already reads -L "/tmp/private - sdk" as two arguments, but
each field was then split again before every whitespace-led dash, so
go.build_paths reported /tmp/private instead of the retained directory.
Split again only a field that begins with a flag, after any package
selector, as a quoted "-L dir -s -w" does. Any other field is one
argument and is kept whole, in -ldflags, -extldflags and CGO flags.
* fix(audit): keep coverage unknown for an unread packaged image
When a listed package member is a native image but its first read
fails, examinePackagedBinary returned before probePackagedImage could
mark its possible embedded package unexamined. Coverage stayed complete
and javascript.source_map_sources could report not_observed for a
payload nobody read.
Mark member coverage unknown wherever a native member goes unread,
including an encrypted one, as an image the probe could not read
already does, and say so in the limitations.
* fix(audit): read rooted Go tool path arguments whole
`-L "/tmp/private,sdk"` and `-L=/tmp/a=b` name one directory, so a `,` or
`=` in a documented path flag's argument is literal. `-trimpath` keeps its
prefix=replacement structure.
* fix(audit): count an unread packaged member once
* fix(audit): keep trimpath rewrites and directory fields apart from selectors
* fix(audit): keep a .map unsettled once a declaration was discarded
* fix(audit): skip env option arguments when reading a Node shebang
* fix(audit): keep companion coverage unresolved for a generic .map link
* fix(audit): count a dropped linker-map guess as a skipped companion
* fix(audit): read env settings after -- in a Node shebang
* fix(audit): route a selected native image named .map by its format
A directly selected or listed native image has no package format, so
examineMember skipped its native-first branch and sent a file such as
release.map through map routing. Its bytes then became a linker-map
guess and marked native.debug_companions exposed. Native format now
outranks the name for every member, packaged or not.
* fix(audit): read forwarded -rpath and -rpath-link as linker paths
A cgo build with CGO_LDFLAGS=-Wl,-rpath,private-runtime kept the
relative directory, but the forwarded linker parser only knew -L, -T,
-I, --library-path, --dynamic-linker and --script, so go.build_paths
reported not_observed. Add -rpath and -rpath-link to the same parser,
in the attached, = and next-field forms. Loader-expanded values such as
$ORIGIN/../lib and @loader_path/Frameworks name no build-host directory
and stay unreported.
* fix(audit): read each entry of a forwarded linker search list
-rpath and -rpath-link take a colon-separated search list. The loader
token filter tested the whole list, so -Wl,-rpath,$ORIGIN:/opt/private-runtime
dropped /opt/private-runtime along with $ORIGIN, and the rooted-path pass
cannot see an entry that follows a colon. Split each search list into its
entries and drop only the loader-expanded ones.
* fix(audit): expand loader tokens only in a linker search list
The runtime loader expands $ORIGIN and @loader_path only in a -rpath or
-rpath-link search list. The token filter also ran on the argument of -T,
-L and -I, so -Wl,-T,$ORIGIN.ld dropped a literal linker script path and
a complete read could report go.build_paths as not observed. Search list
entries keep the filter; every other linker path argument is kept as is.
* fix(audit): count a .map link beside a selected file as a skipped companion
The sibling scan skipped any .map entry that was not a regular file, so a
symlink such as symbols.map -> payload beside a selected executable left
debug companion coverage at not observed. The reader never follows links,
so the linker map such a link may name is unread, not absent. Count a
generic .map sibling link as a skipped companion without following it,
as noteUnfollowedMapLink already does inside a selected directory.
* fix(audit): split a linker search list only for an ELF image
Only the ELF linker reads a -rpath or -rpath-link argument as a
colon-separated list. The Mach-O linker stores each -rpath argument as one
directory, so -Wl,-rpath,@loader_path/lib:extra is a single loader-relative
entry, yet it was split and extra was reported as a build path. Carry the
native image format into the Go flag reader and split search lists only for
ELF; other formats read the whole argument as one entry.
* fix(audit): expand only the image loader's runtime tokens
A runtime search path token is expanded only by the loader of the image's
format. The ELF loader expands $ORIGIN, $LIB and $PLATFORM; dyld expands
@executable_path, @loader_path and @rpath. Each is literal text to the
other loader, so -Wl,-rpath,$ORIGIN:/opt/private-runtime on a Mach-O image
names a literal directory, yet it was dropped and go.build_paths reported
not_observed. Pick the token set from the native image format; the PE
loader reads no search list, so it expands none.
* fix(audit): keep a declared .map link beside a selected script a source map
The sibling scan counted any .map symlink as a skipped debug companion
before checking whether the selected script declared it as its source
map. classifySiblingMap already excludes a declared target that is a
regular file, so a declared symbols.map link added a false unknown to
debug_companions. Apply the declared-target check before either file-type
branch; noteUnreachedTargets still counts the unread map as skipped.
* fix(audit): byte-check members whose kind is only an inventory path role
Inventory gives a packaged member a role from its name, such as resource
for payload.json or source-map for payload.map. The packaged-format guard
treated any kind other than "file" as owner-stated, so a nested ASAR an
ASAR lists under one of those names skipped signature recognition and
cleared coverage. Track whether the package owner stated the kind (Bun
sourcemap region, SEA main script) and only skip the byte check then.
* fix(audit): read Go's linker -r setting as a runtime search list
go tool link -r sets the ELF dynamic linker search path, dir1:dir2:...,
which the linker writes to RUNPATH. It was read as one whole path, so a
release built with -ldflags='-r=$ORIGIN/../lib' reported the
loader-relative entry as a build path and go.build_paths as exposed.
Read -r entry by entry with the same image-loader-aware split and token
filter a forwarded -rpath uses: ELF splits at ':' and drops $ORIGIN
entries; Mach-O keeps the argument as one directory.
* fix(audit): keep a selected package executable's native carrier format
A directly selected PyInstaller executable named release.map recorded the
package format as its member format, even though its ELF or PE carrier was
already recognized. examineMember then missed the native-first branch and
treated the executable as a linker map, reporting a debug companion.
Forward the native carrier format for the selected file, as listed members
already do.
* fix(audit): keep coverage unknown for an unread unclassified member
A packaged member with no format of its own, such as a PyInstaller
payload.bin, recorded only a skipped text member when its read failed
before the header. Member coverage then stayed complete, though the
member could be a native image or carry a nested package. Leave
coverage unknown and say which member could not be read, as an unread
native member already does.
* fix(audit): keep ASAR header admission distinct from max_file_bytes
A directory holding an ASAR whose header exceeds the header admission
was reported as a file-size refusal with max_file_bytes advice, which
cannot fix it. Report the header admission as its own bound instead.
* fix(audit): thread the shared ASAR header admission into release exposure
createReleaseExposureService built ReleaseExposureReader with no admission,
so its inventory and every reopened ASAR reader stayed on the 16 MiB
default and ignored REA_ASAR_MAX_HEADER_BYTES and asar.max_header_bytes.
Resolve the admission in the composition with runtimeAsarHeaderAdmission,
as the Electron and V8 observation providers do, and pass it to both
inventoryArtifactInScope calls, the reopened container readers, and the
nested ASAR signature probe. The refusal now names the setting that can
raise it instead of claiming there is no runtime override.
* fix(audit): keep a nested ASAR probe stopped at the admission undecided
The release exposure reader treated an ASAR signature probe that stopped
at the header admission as "not an ASAR". A packaged member such as
payload.json holding an ASAR whose JSON starts past asar.max_header_bytes
was then read as plain text, its inner maps went unread, and
javascript.source_map_sources could stay not_observed.
A probe that reaches the admission limit, or runs out of a prefix read
after its extents parse, now marks package coverage unknown and records
a limitation, while the member is still examined as text.
* fix(cli): parse audit-release-exposure --max-file-bytes as a decimal token
Main now requires every numeric CLI option to admit decimal tokens and
reject 0x10 and 1e3 (tests/boundary/cli/cliDecimalArguments.test.ts).
Wrap the release exposure maxFileBytes option in cliDecimalField like the
other maxFileBytes options, so the domain field keeps its bounds and default.
* docs(specs): add the release exposure audit specification
Add spec.md, plan.md and tasks.md under docs/specs/artifacts/release-exposure/
as docs/development/documentation.md requires for a new feature, and list
them in docs/specs/README.md. The existing guide at docs/release-exposure.md
keeps describing current behavior and its route is unchanged.
* fix(audit): bind unpacked ASAR member reads to their inventoried digests
A selected ASAR is captured and checked against its inventoried digest, which
binds packed members. An unpacked member is read from its .unpacked companion
on disk instead, and readContainerMember and readEntryBytes never compared
those bytes with the member digest inventory recorded, so a companion
replaced between inventory and the scan was accepted.
readContainerMember now passes the member's inventoried digest for unpacked
entries, and readStreamBounded hashes the full stream, draining past the read
allowance when needed, and fails with "ASAR member changed before
interpretation", which surfaces as an artifact_changed error like the
container check. A regression test replaces a companion after inventory. The
guide, spec, plan and tasks describe the binding.
* fix(audit): let stated JavaScript roles outrank a .map name
isDeclaredMap() routed any member whose name ended in .map to map
handling before the owner's stated role or a page's script declaration
was considered. A Node SEA main script at boot.map, which the SEA reader
marks as javascript, and a .map script an HTML file loads both became
linker-map guesses, so their inline maps were never read and
native.debug_companions was reported exposed.
An owner-stated source-map role or a declared map target still makes a
member a map. Otherwise a stated javascript kind or a script target now
wins, and only then does the .map suffix, or the inventory path role that
repeats it, decide. Regression tests cover both cases, and the guide
notes that a SEA main script is read as a script whatever it is called.
* fix(audit): keep coverage unknown when a packaged text member fails to read
A compressed member named as text, such as payload.json in an unexpanded
PyInstaller host, can fail inflation before any header is returned. The
.bin case already leaves member coverage unknown because an unread header
may hide a nested image or package, but examineTextMember() only counted
the member as skipped text, so otherwise complete coverage stayed
complete and package-dependent checks could settle.
An unread packaged member whose kind its package did not state now goes
through noteUnreadBinary(), which counts it as skipped text, marks
coverage unknown, and records the limitation. A regression test corrupts
the zlib stream of payload.json in a CArchive host and checks the intact
member keeps coverage complete. The guide describes the rule.
* fix(audit): keep the unpacked ASAR digest check inside the read allowance
ea87cf8 made readStreamBounded hash an unpacked ASAR companion to its end
so it could compare against the inventoried digest, which drained the
stream past the read allowance. A 1 GiB unpacked module was read in full
for a 4 KiB header probe and again for a package probe, and a companion
that grew after inventory had no byte limit on that path.
readStreamBounded now stops at the allowance as every other member read
does, and compares the digest only when the member ended within the
allowance. A companion past the allowance stays over_allowance without a
digest verification. A test counts the bytes each scan read pulls from an
8 MiB companion. The guide and spec state the bound.
* fix(audit): read a script target whose bytes are a source map as a map
|
||
|
|
0ae186e196 |
fix(settings): classify caller-selected limits as parameter updates
analysis_timeout_ms, max_heap_mb, and command_timeout_ms keep the source chosen by the caller, the runtime override, or the built-in default. A request value reports update_mode parameter because update_analysis_settings cannot change that call. |
||
|
|
a16f5f4b5d |
fix(recovery): preserve bounded Wakaru failure and cleanup facts (#10087)
* fix(javascript): retain Wakaru diagnostics and cleanup ownership * fix(recovery): preserve launch failure with late cancellation * fix(recovery): retain cancellation through provider cleanup |
||
|
|
8a2eb4ab61 |
fix(source-maps): preserve decoder lifecycle facts (#10069)
* fix(source-maps): preserve decoder lifecycle facts * fix(source-maps): preserve preparation failure on cancellation * fix(source-maps): retain preparation and retry cleanup facts |
||
|
|
a14a0c20ed |
fix(javascript): authenticate transfer bytes before decoding (#10078)
fix(javascript): authenticate raw analysis transfer bytes |
||
|
|
13abfdadff |
fix(workers): preserve artifact failures through cleanup (#10055)
* fix(browser): preserve worker artifact failures through cleanup * fix(javascript): preserve checkpoint failures before late cancellation |
||
|
|
3c4be703cd | test: consolidate JavaScript and provider fixture coverage | ||
|
|
cb4e5cfbff |
feat(analysis): make resource budgets recoverable across CLI and MCP (#9706)
* refactor(analysis): centralize resource budgets and recovery facts * feat(analysis): expose ASAR and Ghidra runtime admission controls * feat(artifacts): expose reader admission and preserve limited recognition * feat(javascript): expose recoverable semantic precision budgets * feat(web): add recoverable source-map budgets and compact retained views * feat(web): make historical capture decoding budgets recoverable * fix(desktop): enforce selected view policies across capture and export * feat(runtime): make Frida and LLDB retention budgets selectable * feat(native): expose diagnostic budgets and preserve exhaustion causes * feat(managed): expose recoverable snapshot and representation budgets * feat(metadata): make Go and Rust inspection budgets recoverable * feat(wasm): expose representation and producer admissions * feat(evm): expose per-call worker resource budgets * feat(android): make resource and string-pool omissions recoverable * feat(producers): expose command and recorded-capture budgets * docs(analysis): record recovery contracts and integrated validation * fix(docs): link calibration oracle from published verification pages * fix(docs): restore desktop task anchors and receipt links * test(analysis): align fixtures with selectable budget contracts * fix(analysis): remove source-location projector dependency cycle * test(analysis): refresh budget recovery and verifier regressions * test(analysis): preserve format and publication recovery expectations * test(windows): align conformance with owned runtime admission * fix(desktop): preserve selected alias kinds in exported state * test(analysis): align provider fixtures with recoverable budgets * test(desktop): validate emitted alias metadata structurally * fix(ghidra): classify bounded Windows endpoint refusals * test(cli): assert selectable artifact admission recovery * fix(cli): preserve capture provenance in environment builds |
||
|
|
2c27c2a43b |
feat(electron): report V8 cachedData compilation boundaries (#9501)
* feat(electron): report V8 cachedData execution boundaries
analyze-javascript-application treated new vm.Script(source, {cachedData}) and vm.compileFunction(..., {cachedData}) as ordinary source. V8 deserializes previously compiled bytecode for those calls, so an Electron preload wrapper that delegates its whole contextBridge and IPC surface to a .cache/.jsc snapshot appeared to have been fully analyzed with zero exposed APIs.
Record each vm compilation with its inert cache path when the cachedData value traces to a readFileSync/readFile of path syntax, and project a cached-data execution unknown plus a loads edge from the owning source. Compilations without a cache stay recorded as no-cached-data so absence remains distinguishable from an unparsed snapshot. Count cachedData executions in the Electron summary and state the coverage limit in the graph limitations.
* style(cli): wrap the native data type path description
The `inspect-native-data-type` argument description line is 82 columns, over the repository's 80-column `.oxfmtrc.json` limit, so `npm run format:check` fails on main and on every branch merged from it. It came in with #9465 and the following commits to this file did not touch it. Reformat the one call the formatter objects to; no behaviour change.
* style(domain): reformat the pending dynamic-code accumulator field
`npm run format:check` fails on this branch, which is what `Static checks` reports: oxfmt wants the `pendingDynamicCode` union on one line. Applying it is the whole change; no behaviour is touched.
* fix(electron): preserve VM callable and cache source uncertainty
* docs(javascript): specify cached-data compilation boundaries
* fix(electron): exclude disabled caches from recovered boundaries
---------
Co-authored-by: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
|
||
|
|
0b1a945d69 |
fix(electron): model view constructors as window-like surfaces (#9571)
* fix(electron): model view constructors as window-like surfaces Electron's static pass recognized a window only through the literal `BrowserWindow` constructor, so `BaseWindow`, `BrowserView` and `WebContentsView` produced no node and their literal `webPreferences` were invisible. IPC registrations reached through such a view's own `webContents.ipc` were dropped too, because the receiver resolver had the same single-constructor gate -- VS Code alone registers seven channels this way, and a shipped sample of four applications put 29 percent of window construction sites on an unmodeled constructor. Read webPreferences through one constructor set shared by the construction inspector and the IPC receiver resolver. The finding only carries the new `window_constructor` field when the site is not `BrowserWindow`, so existing projections and their evidence stay byte-identical. A non-BrowserWindow owner is not admitted for `loadFile`/`loadURL` on itself: only BrowserWindow exposes those directly. * fix(electron): keep the view constructor label lookup nullable Observation labels are nullable in the application graph schema, so the byLabel lookup failed tsc with TS18047 and took the Static checks job down with it. --------- Co-authored-by: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
8358cfcab3 |
fix(javascript): preserve cancellation during recovery report reads (#9605)
* fix(javascript): preserve recovery report cancellation * fix(javascript): retain recovery output on report failures |
||
|
|
891371e738 |
fix(objdump): reflect observed launch failure in discovery availability (#9051)
* fix(objdump): reflect observed launch failure in discovery availability Distinguish a statically registered standalone command from an executable whose launch has failed in the active server session. Discovery leaves unprobed commands optimistically available, reports an observed launch failure as provider_unavailable with the command remediation, keeps the tool callable for retries, and clears the failure after a subsequent successful launch. Fixes #8826. * test(reverse): verify overlapping command launch dispatch ordering * test(reverse): unblock gated test workers before awaiting service closure * test(reverse): bound lifecycle acknowledgement and join launched workers * fix(reverse): distinguish host capacity exhaustion from command launch failures * fix(reverse): preserve host capacity across Linux process ownership preparation * fix(reverse): exclude process ownership admission failures from command launch state * fix(reverse): preserve Darwin process ownership preparation error across command launch * fix(reverse): disambiguate cleanup declaration in provider observation * fix(reverse): preserve command deadline timeout during Darwin ownership preparation * fix(reverse): isolate Darwin baseline ps errors and provide platform-aware admission guidance * fix(reverse): rely on typed baseline admission failures and use owning repair formatter in tests * test(reverse): use owning formatters for process ownership remediation assertions * fix(reverse): restrict Linux ownership prerequisite remediation to missing ps and preserve system error codes * fix(reverse): retain typed process ownership prerequisite with preserved error codes * fix(reverse): remove unvalidated error label fallbacks and keep admission tags out of system_code * fix(reverse): keep Windows native runner failures out of command-launch state * fix(process): preserve current_process_unreported refusal in Linux provider readiness * fix(process): distinguish no-code ps failure from missing ps and cover rizin launch failure * fix(windows): classify process_spawn host-control rejections as RuntimeControlUnavailableError |
||
|
|
2c6f981667 | fix(javascript): hash Electron call paths from canonical values | ||
|
|
b46f4fcebd |
fix(javascript): preserve loader authority for exact suffixes (#9477)
* fix(javascript): require exact loader suffix case * fix(javascript): share exact loader mode across import resolution * test(process): align symlink fixture with filesystem checkpoints * test(javascript): normalize the module resolution oracle path separators * test(frida): assert the CLI spawn Evidence contract * test(mcp): use an unsupported analysis-view parent * test(browser): separate source-location line bounds from parity * fix(javascript): preserve uncertain loader provenance * test(javascript): cover uncertain require resolution * fix(javascript): retain conditional Electron evidence * fix(javascript): preserve timed semantic provenance * fix(javascript): retain conditional builtin effects * test(javascript): distinguish bundled host authority * fix(javascript): preserve nested loader invocation identity * test(javascript): qualify Electron fixture authority * fix(javascript): preserve loader invocation authority * fix(javascript): respect source order for resolver escapes * fix(javascript): check nested loader callable mutations * fix(javascript): retain conditional constructor requests * fix(reference): retain constructor loader relationships * fix(reference): follow nested loader callable paths * refactor(javascript): share callable mutation interpretation * fix(javascript): require exact package loader suffixes * refactor(javascript): unify conditional relation evidence * refactor(javascript): unify conditional node evidence * fix(javascript): retain unknown authority for mixed case sources * fix(javascript): preserve loader uncertainty for dotfiles * fix(reference): classify javascript suffix dotfiles * test(reference): cover suffix dotfiles through cli * fix(javascript): retain equivalent conditional built-in origins * fix(javascript): preserve wrapped resolver operation * fix(javascript): retain nested conditional built-in receivers * test(javascript): declare CommonJS in native addon fixtures * fix(javascript): retain wrapped resolver candidates * style: format merged native command schema * fix(javascript): preserve uncertain loader authority * test(javascript): require candidate preload evidence * test(javascript): cover reference loader member writes --------- Co-authored-by: ShuaixinHuang <1836656514@qq.com> |
||
|
|
5044e20171 |
test: focus diagnostics and evidence checks on behavior (#9303)
* test: focus configuration diagnostics on their owners Preserve shape errors, selected paths, recovery guidance, and unchanged-file behavior across parser, setup, and uninstall boundaries. * test: focus artifact and evidence checks on behavior Retain format, identity, malformed-input, and cleanup coverage while removing fixed prose and closing the admitted test source. * refactor(debugger): use configured session admission limits * test: focus evidence and diagnostics on behavior * fix(test): restore verifier export and formatting * test(config): verify debugger limit ranges * test(rizin): keep fixture executable authoritative * test(rizin): isolate debugger fixture environment |
||
|
|
352a846127 |
test: reduce brittle assertions and test-only runtime paths (#9289)
* test: focus assertions on behavioral evidence Prune redundant and wording-coupled checks while retaining diagnostic, parser, recovery, and cleanup coverage. * refactor: remove test-only wrappers and duplicate checks Exercise production operations through test fixtures, remove unused adapters, and keep managed-member uncertainty guidance under its existing owner. * test: focus process validation on diagnostic facts * refactor: remove test-only runtime helpers Move semantic evidence fixture setup out of runtime and remove unused Windows settle recovery helpers while checking configured defaults independently. * test: focus artifact diagnostics on format facts * test: verify retained cleanup guidance delivery |
||
|
|
a67525cdf1 |
docs: organize canonical documentation layout and verify new pages (#2791)
* docs: organize canonical documentation layout (URGENTE) Group all existing authored guides by domain and ownership, expose complete navigation, and preserve their public routes. Update physical path consumers and release configuration while retaining historical records. Document domain-based specs and ADR slugs without global numbering. Co-Authored-By: Codex <noreply@openai.com> * fix(docs): honor home layout in all-page route verification * style: format reviewed source changes * fix(docs): preserve routes and navigation cache inputs * fix: repair the static-check failures on the default branch (#2895) * fix: repair the static-check failures on the default branch The default branch fails its own required `Static checks` job three ways, so every pull request reports that job as failed regardless of its own change. - `npm run format:check` reports `src/domain/functionComparison.test.ts` and `src/ida/IdaOperationRunner.ts`. - `npm run lint` reports a duplicate `import { join } from "node:path"` in `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17). - `npm run typecheck` reports `format: "devin"` missing from the client format union in `src/application/SupportedClients.ts`, and an unchecked index in `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is inferred as `string[][]`. Apply the pinned formatter, drop the duplicate import, list the `"devin"` format that its own definition already uses, and mark the pair array `as const`. Validation: `npm run check:fast` and `npm run format:check` pass. * fix(setup): keep Devin on the JSON configuration dialect --------- Co-authored-by: 吴佳浩 <wujiahao@supremind.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> * fix(docs): update links after guide relocation * docs: correct verified documentation route counts * fix(docs): update browser capture guide link after move (#2820) Refresh gettext protected-link comments alongside the authored href. Co-authored-by: Codex <noreply@openai.com> * fix(docs): include http3 lab in stable routes * fix(docs): preserve historical release evidence and links * fix(ghidra): restore Windows verifier identity import * docs(wakaru): preserve pinned upstream policy link * docs(index): retain recently added guide links * docs(mcp): preserve parent retention clarification * fix(cli): preserve standalone import guidance * fix(test): preserve translated guide link drift coverage --------- Co-authored-by: Matheus Breguêz <matbrgz@gmail.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: morluto <17176810+morluto@users.noreply.github.com> Co-authored-by: 吴佳浩Alben <35291372+XiaoBinGan@users.noreply.github.com> Co-authored-by: 吴佳浩 <wujiahao@supremind.com> |
||
|
|
110932cd5e | test: clarify source map and worker diagnostics | ||
|
|
1596d6a275 | test: reduce wording coupling and prune redundant coverage | ||
|
|
562779bd71 |
fix(mcp): advertise absolute paths for tools that reject relative inputs (#9179)
* fix(mcp): advertise absolute paths for tools that reject relative inputs The domain schemas accepted relative paths, then handlers rejected them with isAbsolute. Those inputs now use absoluteLocalPathStringSchema, and the duplicate handler checks are gone. * fix(javascript): own recovery path admission in the schema Relative recovery paths now fail in absoluteLocalPathStringSchema, including the additional_paths index. Drop the duplicate handler check, and make the CLI, MCP, and tools/list tests assert that schema fact. * test: assert absolute-path facts instead of error prose Recovery and web-script tests keep the field, format code, and regex expectation. They no longer freeze the schema's explanatory sentence. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
55ee36809d |
fix(javascript): apply package type scope to application sources (#7883)
* fix(javascript): apply package type scope to application sources Application analysis parsed .js sources without their package scope, so an unbound require in a type-module package became a resolved CommonJS dependency. The parent now observes each source's nearest same-container package.json, stopping at node_modules, and the worker parses with that package type as reference imports already do. Fixes #7323 * fix(javascript): keep package type unknown behind unavailable manifests The package-type lookup indexed only readable files, so a nearer package.json whose bytes were unavailable was skipped and an ancestor's "type" applied to sources it does not own. Index unavailable manifests by container and directory too, and stop the walk with "unknown" when one is the nearest owner, as the Next app-context lookup already does. * fix(javascript): keep Electron preloads outside module package scope Electron's preload loader ignores a package's "type": "module" and gives a .js preload `require`; ESM preloads need the .mjs suffix. Applying the package type to every .js source marked such a preload as an ES module, so its `require("electron")` edges and IPC pairing disappeared. A source that requires an Electron module now keeps the context REA inferred before package scope was applied. Node-loaded sources in a module scope still drop unbound `require`. * fix(javascript): admit Electron script loaders only on renderer evidence The previous commit dropped a module package type whenever a source required an Electron module. A Node-loaded ES module that requires Electron, or one whose Electron call goes through a local `require`, then regained the false require edges the package scope removes. The parser applies the package type unconditionally again. The worker re-reads a package-module script that requires an Electron module once outside the package scope. The source keeps that context only when the static pass there directly observes a contextBridge exposure or a renderer IPC operation, which only Electron's renderer-side loaders provide. * fix(javascript): check Electron renderer evidence without a second static pass |
||
|
|
99bcd3e4e0 |
fix(javascript): report empty Electron coverage instead of silent zeroes (#8332)
* fix(javascript): report empty Electron coverage instead of silent zeroes `analyze_javascript_application` reported `browser_windows: 0` and `ipc.operations: 0` with only generic partial/unknown flags, so a bundle that imports `electron` but whose Electron facts were not recovered read exactly like an application with no IPC at all. Issue #8201 is that false negative on a real Rolldown bundle. Two additions, both scoped to "Electron is referenced but nothing was recovered": **A machine-readable indicator.** `electron_summary` gains `electron_semantics: "recovered" | "empty"`. It is absent when no analyzed source links an Electron module, so its presence distinguishes "not an Electron application" from "Electron coverage is empty". It follows the existing `protocol_registrations.exactOptional()` precedent, so previously captured evidence stays valid. **A graph limitation.** The limitation list already carried a note when at least one Electron fact was recovered but said nothing when zero were. It now states that zero IPC operations and zero BrowserWindows mean empty coverage rather than absence. `electronModuleReferenced` is the single owner of the module test. It reuses `ELECTRON_MODULE`, which matches exactly the supported entry points (`electron`, `electron/common`, `/main`, `/renderer`, `/utility`), so `electron-helper` does not count, and it ignores type-only links because importing Electron types promises no boundary fact. Five tests cover recovered, empty, not-referenced, type-only, and supported subpath versus unrelated package. The empty, recovered and type-only cases fail on unmodified `main`. * chore: retrigger title and readiness checks after the title was corrected * fix(javascript): report Electron coverage from retained facts Four review findings on the coverage indicator. **A rejected application projection hid the reference.** A file whose expanded relationships exceed the result budget is replaced by a placeholder with no module links before the summary runs, while `graphLimitations` reads the raw analysis. The same response could then warn in prose and omit the field. The summary now takes the retained analysis for coverage only, and both outputs read one `electronSemanticsState`, so they cannot disagree. **A skipped semantic analysis hid the reference too.** `electronModuleReferenced` read only `semantic.ir.moduleLinks`, which is absent when semantic analysis is skipped for a budget and drops `import("electron")` or `module.require("electron")` forms. It now falls back to the retained `javascript.references`, which the static producer records for those inputs, while still excluding `type-import` links when the richer owner is available. `electronBoundaryFactCount` is now the single owner of the fact total, replacing a duplicate inline reduce in the graph builder. **Omission no longer claims absence.** The schema comment said a missing `electron_semantics` means the application does not use Electron. The predicate only establishes that no retained fact names one, and unread sources, failed analysis, and dynamic module names can hide its use, so the contract now says unknown. Two regressions cover a rejected projection and a skipped semantic analysis; both fail on the previous commit. * fix(javascript): count a dynamic Electron import as coverage Review finding: `electronModuleReferenced` returned as soon as module links existed, so a literal dynamic import was ignored. Verified against the two fact owners: import("electron") -> references: [dynamic-import electron] moduleLinks: [] require("electron") -> references: [require electron] moduleLinks: [require electron] An application that only loads Electron through `import("electron")` therefore got neither `electron_semantics: "empty"` nor the empty-coverage warning, and the zero counts stayed unexplained. The two owners now answer their own half instead of one short-circuiting the other. Module links answer a runtime static import or require and keep excluding `type-import`; the retained reference is read for every kind except `static-import`, which is exactly the type-only risk. A dynamic specifier is still never counted by either owner, so this remains an observed-reference claim rather than an absence claim. The regression uses `import("electron")` and fails on the previous commit. * fix(javascript): read only module-loading Electron references Two review findings, both verified against the static reference producer. **A retained runtime static import was skipped.** The excluded kind was meant to protect the type-only distinction, but the static analyzer records a whole `import type { IpcMain } from "electron"` declaration as no reference at all: import type { IpcMain } from "electron" -> references: [] import { app } from "electron" -> references: [static-import electron] require("electron") -> references: [require electron] import("electron") -> references: [dynamic-import electron] new Worker(new URL("electron", m)) -> references: [worker electron] When semantic analysis is skipped for a budget the module links are absent, so that exclusion dropped a real runtime ESM import and left the zero counts unexplained. **A worker URL path is not an Electron module.** `new Worker(new URL("electron", import.meta.url))` records a `worker` reference whose specifier is a path relative to the importing source, so counting it reported an ordinary worker file as `electron_semantics: "empty"`. `ELECTRON_REFERENCE_KINDS` is now an explicit allowlist of the kinds that load a module by package specifier — `static-import`, `dynamic-import` and `require` — so `worker` and `service-worker` URL paths are excluded. Module links are still read first for the type-only distinction. Three regressions cover a skipped-semantics ESM import, a skipped-semantics whole type-only import, and a worker URL path; two of them fail on the previous commit. * fix(javascript): own Electron applicability in the static producer Review finding. A `worker` reference records a URL relative to the importing source, so `new Worker(new URL("electron", import.meta.url))` names a local file and is not an Electron module. The boundary owner already read only module-loading reference kinds, but `finalizeStaticAnalysis` still treated every matching static reference as `analysis_coverage.applicability.electron: "observed"`, which `javascriptStaticSourceCoverageSummary` publishes. One response could therefore say Electron was observed in its coverage view while the Electron summary omitted `electron_semantics`. `ELECTRON_REFERENCE_KINDS` now lives next to `ELECTRON_MODULE` in the domain owner and is consumed by both the static producer and the Electron boundary owner, so the two outputs cannot disagree. A worker URL path is `unknown` for both, while a `require("electron")` is `observed` for both. The regression asserts the domain applicability fact and the boundary summary agree for a worker URL path; it fails when the producer stops filtering by kind. * fix(javascript): require a loaded Electron module for applicability Review finding. A CommonJS `require.resolve("electron")` records a `require` reference with `operation: "resolve"`: it locates the module without loading it, so no Electron boundary fact is expected. Both predicates dropped the operation, so such a source reported `electron_semantics: "empty"` and the missing-coverage warning even though Electron was never loaded. Measured on the static producer: require.resolve("electron") -> references: [require resolve electron] applicability.electron: unknown require("electron") -> references: [require load electron] applicability.electron: observed import("electron") -> references: [dynamic-import load electron] applicability.electron: observed `electronModuleReferenced` and `finalizeStaticAnalysis` now both require `operation === "load"`, so the boundary summary and the coverage view stay aligned and reachability-only references no longer claim missing coverage. The regression asserts a resolve-only source produces neither the field nor the warning, and it fails when the operation check is removed. * fix(javascript): classify Electron loads in the static fact owner Review finding, and the correct home for the previous two rounds of the same complaint. A Webpack/Rspack factory may name a local module `"electron"`, and the static producer then records a loaded `require` reference whose specifier is that bundle module key. Treating the key as a package specifier reported `electron_semantics: "empty"` plus the missing-coverage warning for a bundle that never loads Electron. Three changes, all in the domain owner, so no consumer re-derives the question: - `JavaScriptModuleRangeIndex.hasKey` answers whether a specifier is a recovered bundle module key. A `require` whose specifier is such a key loads a module inside the artifact. - `electronObserved` in `finalizeStaticAnalysis` now requires a loaded module-load reference whose specifier is not a bundle key. The published `analysis_coverage.applicability.electron` therefore owns every exclusion: `type-import`, `require.resolve`, `worker`/`service-worker` URL paths, and bundle-local keys. - `electronModuleReferenced` consumes that owned fact instead of re-deriving it, keeping the boundary summary and the coverage view from disagreeing. Historical evidence without the field still falls back to the retained references. Measured: bundle-local module ID "electron" -> applicability unknown require("electron") -> applicability observed webpack external n(45840) -> applicability observed The regression covers both the local key and the real external in the same factory shape; it fails without the bundle-key exclusion. * fix(javascript): identify a bundle module by its loader, not its key Both review findings were right, and they show why the previous key-set approach was wrong: bundle-key membership is a property of the file, but whether a specifier names a module inside the artifact is a property of the reference. `JavaScriptStaticReference` now records the loader that produced it, and `electronObserved` excludes `factory-loader` references instead of every specifier that happens to match a recovered module key. Measured on Node 24.22.1: local module keyed "electron" -> unknown (factory-loader) external 45840 = require("electron") -> observed (commonjs-loader) factory keyed "electron" that loads the pkg -> observed (commonjs-loader) The third case is the regression: a bundle whose factory is *named* `"electron"` but whose body does `e.exports = require("electron")` is a real Electron load, and the old key-set check suppressed it. The real load keeps its `commonjs-loader` identity even when the same specifier also names a factory, so one response can rely on the loader while the other relies on the key without either lying. `JavaScriptModuleRangeIndex.hasKey` is removed; it answered the wrong question. One regression covers all three shapes and fails when the `factory-loader` exclusion is dropped. * fix(javascript): carry the reference loader across the worker boundary The worker schema is strict, so the new `loader` field broke the worker handshake: `unrecognized_keys` on every `references` entry. That surfaced in CI as both a worker-schema test failure and a package-baseline failure reporting `worker_failure_reason: "io"` for a one-file Electron app. `referenceShape` now accepts the same three loader identities as the domain type, so the fact survives the worker boundary instead of collapsing every analysis to an execution failure. Verified: `JavaScriptAnalysisWorkerSchemas.test.ts` 10 passed, and the full domain/application/javascript suite is 5484 passed | 10 skipped. The remaining `SourceMapCommand` and `DarwinHelperCache` findings are present on unmodified `main` and are not from this change. * fix(javascript): remove the superseded key set and forward a deferred loader Two review findings. **The `keys` set is dead.** `JavaScriptModuleRangeIndex.keys` is left over from the abandoned key-membership approach: the loader-identity refactor removed `hasKey` and the write in `add`, so nothing reads it. Removed. **The deferred require path dropped the loader identity.** `requireCallSpecifier` returns a `loader` for `commonjs-loader`, `factory-loader` and `create-require`, and the direct `addReference` call forwards it, but `finishModuleRequireCalls` did not. A `createRequire` loader saved under a member literally named `require` therefore lost its identity: import { createRequire } from "node:module"; const holder = { require: createRequire(import.meta.url) }; holder.require("x"); before: require "x" with loader undefined after: require "x" with loader "create-require" Three regressions cover it; one fails without the change. I did **not** change the inline-type-only import case. `isTypeOnlyImportDeclaration` deliberately keeps a declaration whose bindings are all inline type-only, because `hasUncertainTypeOnlyModuleSideEffect` reports that decision as `type-only-module-side-effect` uncertainty: whether TypeScript emits the import depends on the consumer's compiler options. Narrowing it to erased broke `javascriptStaticCoverage.test.ts` and `javascriptSemanticAnalysis.require_links.test.ts`, which assert exactly that contract. If Electron applicability should ignore that reference, the decision belongs where applicability is derived, not in the shared declaration predicate — say the word and I will do it there instead. * fix(javascript): keep a commonjs-loader reference out of the bundle module index Review finding. `finalizeLocatedFindings` attaches `module_runtime` to every finding that sits inside a factory module range, whoever produced it. `resolveReference` then sent every reference carrying `module_runtime` through the bundle-module lookup, so a real CommonJS load inside a factory body resolved to the local module key that shared its name: "electron": (e, t, n) => { e.exports = require("electron") } fact: specifier "electron", loader "commonjs-loader", module_key "electron" before: resolved through the bundle module index to `#module:electron` after: resolves as an external package specifier Only a `factory-loader` specifier names a recovered bundle module key, which is what `loader` already records after the loader-identity change. The module lookup is now gated on it, and an absent `loader` keeps the previous behaviour for older findings. |
||
|
|
4362a0848e |
fix(javascript): transient Windows private-runtime source-transfer (#8769)
* fix(javascript): transient Windows private-runtime source-transfer Parent source-transfer into the Windows private runtime root failed with EPERM on path-based exclusive create. Write through a native transient private-runtime path that closes the handle after flush so per-job rm still works, and yield around the sync write so abort deadlines can fire. * fix(javascript): yield timer phase before Windows source-transfer write |
||
|
|
4a01211f11 |
fix(javascript): keep static facts after semantic results use the parent budget (#8648)
Static checkpoints were admitted against the same budget as semantic and application results, half of the parent's free heap. Once those charges used it, the next checkpoint stopped the analysis and every remaining source lost its static facts, with most of the parent heap still free. Semantic and application results still stop at that budget. Static checkpoints may now continue to three quarters of the free heap while the live heap also has room for another copy of what it holds. Without that room, admission falls back to the result budget. The live condition is needed because the limit V8 reports counts young-generation capacity that retained objects cannot use: without it, the parent aborted on heap exhaustion at small heap limits. Reserved relationships are given up only when the larger share runs short. A stop still fails with a typed error, which now reports the limit that applied, what was available, the live heap in use and what the checkpoint needed. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e18594b247 |
refactor(composition): unify capability bindings and cleanup ownership (#8441)
Bind typed service creation, observed availability and retryable cleanup in one composition owner. Reuse selected CLI/MCP factories and canonical contract groups without copying provider operation inventories. Closes #8429. Refs #740. Validated paired real application workflows, actual local Codex CLI Terra/high use, complete Evidence and Unknown checkpoint parity, compiler-backed import boundaries, SDK schemas and final real mixed routing. Automated review findings were fixed at their producing owners. Existing exact-base CodeQL alerts are documented on the PR under the owner-authorized unrelated-check exception; no global alerts or security rules were changed. Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning) |
||
|
|
47fa6ab379 |
feat(electron): report custom URL protocol registrations
Expose static Electron protocol call facts through the shared application graph and existing CLI/MCP Evidence views. Preserve canonical case-insensitive scheme identity, original spellings, exact source provenance and explicit unknowns; keep registration success and runtime routing unproven. Integration fixes also enforce module-only privileged API ownership, reuse the shared finding-key owner, and align the owning type documentation with the Evidence semantics. Validation and bounded real Obsidian CLI/MCP measurements are recorded in the PR. Co-authored-by: UnknownHacker1 <35694178+UnknownHacker1@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
81378efb71 |
fix(electron): keep literal IPC sends ambiguous beside unresolved handlers (#8120)
* fix(electron): keep literal IPC sends ambiguous beside unresolved handlers A main handler on an unresolved channel can receive any literal renderer send of a compatible mode, but pairing ignored it unless it had a scoped receiver. The send was then reported unpaired, or paired with another handler. Treat an unresolved-channel handler as a competitor that never pairs. The wrapper pass seeds only calls with a literal first argument, so it now records which invocations of a dynamic site it traced. The syntax finding gains `invocation_channels: "literal"` only when every invocation is a traced direct call of an unexported local function supplying a literal channel. Such a site is already represented by its per-invocation findings and does not compete. Fixes #8118 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(electron): keep guarded wrapper registrations competing in IPC pairing A guarded wrapper registration keeps its predicate on a call path and has no IPC finding. It still counted toward `invocation_channels: "literal"`, so pairing lost it: a send on that channel was reported unpaired, or paired uniquely with a direct handler. The enumerated site now carries these channels as `guarded_invocation_channels`, and each one competes for its own channel without pairing. Index each binding's direct call sites by appending in place. Spreading the earlier calls on every reference was quadratic in a file's call count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
395b598383 |
refactor(admission): own inspector, web, and CLI state per host (#8058)
* refactor(admission): own inspector, web, and CLI state per host Replace the process-global inspector, web-bundle, guidance, and JavaScript counters with objects a host passes in, so independent instances do not share admission or cleanup. * fix(admission): keep worker and file cleanup on the host Web-bundle and JavaScript workers retry only their host registry, and each Inspector admission authorizes and closes its own file scope. Browser providers can share one web-bundle admission. * test(inspector): gate one admission's file cleanup The isolation test delayed the first ArtifactResourceScope.retryCleanup call, so a second call on a shared ElectronFileScope still finished. Hold first.files.retryCleanup until the other admission's close finishes, then release and join before restoring the method. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
6fa48f201f |
docs(apk): clarify rotated signer agreement (#7936)
* docs(apk): clarify rotated signer agreement * test(mcp): assert bundle path issues by field compare_bundles reports each relative path as an invalid_format issue instead of one joined diagnostic sentence. * fix(javascript): ignore worker frames for a different source job A failure frame for another job was dequeued as an output error, so a later caller abort lost the race and was not reported as cancellation. * test(flutter): assert ABI selector refusals as structured issues inspect_dart_aot reports the ABI label as an issue on path abi. The message is the selector contract, without an abi: prefix. * fix(javascript): check each worker frame condition once A ready frame is rejected on its own. A non-ready frame for another job keeps waiting. The following id comparison repeated that skip, so it never ran. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> |
||
|
|
54f5cf7e14 |
fix(javascript): retain static facts under projection pressure (#7986)
* fix(javascript): retain static facts under projection pressure * fix(javascript): scope IPC ambiguity to omitted projections * fix(javascript): preserve IPC uncertainty for omitted sources * fix(javascript): qualify IPC pairing by wrapper coverage * fix(javascript): retain provisional IPC wrapper matches |
||
|
|
95f0625781 |
fix(javascript): preserve uncertain with-scope member writes (#7914)
* fix(javascript): preserve uncertain with-scope member writes * fix: retain nested initializer candidates * fix(javascript): admit initializer values in worker transport * fix(tests): remove duplicate MCP test imports |
||
|
|
f9e7571a3d |
feat(javascript): discover semantic call literals in feature traces (#7840)
* feat(javascript): discover semantic call literals in feature traces * fix(javascript): bound retained call literals by transfer capacity * test(javascript): align feature no-match diagnostic |
||
|
|
c66729eca9 | fix(workers): retain cancellation through final cleanup | ||
|
|
a6488a96a9 | fix(javascript): preserve renderer path anchors | ||
|
|
c2b0c955cd | fix(workers): reject malformed UTF-8 in JSON result files | ||
|
|
1d32eb3aa4 |
fix(providers): keep operation environments consistent through launch
Capture one environment snapshot per admitted WABT, JADX, firmware and Wakaru operation. Use it for tool selection, session identity and child launches while preserving configuration updates between operations. Regressions reproduce changed JVM options under an old session key, mixed engine/limiter selection and environment drift between subprocesses. Keep selected-wrapper and cleanup coverage in a shared fixture with separate scenarios. Validation: 115 distinct focused tests passed across the final five-file selection, including seven selected-command cases after refactoring. Fresh build, typecheck, lint and formatting passed. Tests use real subprocess fixtures; no real JADX/WABT/Binwalk/Wakaru engine or native Windows verification is claimed. |
||
|
|
cd68181c90 | fix(providers): preserve report bytes and dictionary facts | ||
|
|
721dd3d1aa | fix(javascript): preserve selected inputs and completed source evidence | ||
|
|
e2d4c0dabb | fix(process): preserve environment snapshots and final cancellation | ||
|
|
86ff3237e1 | fix(paths): preserve selected command, output, and source identities | ||
|
|
69a2faa120 |
feat: add FreeBuff agent support for REA setup (#2736)
* feat: add FreeBuff agent support for REA setup Register FreeBuff as a supported setup client using the shared user agents directory (~/.agents/mcp.json with mcpServers, skills in ~/.agents/skills), which matches what FreeBuff Desktop loads. Adds the client definition, boundary tests, supported-agent docs, and the skill reference client list. * fix(freebuff): detect FreeBuff from its profile directory, not shared .agents The ~/.agents marker made FreeBuff appear installed for any home where REA had installed shared skills (the default skill destination, also Gemini CLI's), producing false doctor failures. Detect FreeBuff from its own fixed profile directory ~/.config/freebuff-desktop instead, and add a regression test covering a home with only the shared agents skill directory. * fix(setup): require product evidence for FreeBuff discovery Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request. * fix(uninstall): retain unverified shared client configuration * fix(clients): preserve scoped removal evidence * fix(doctor): omit undefined selectedClientIds under exactOptionalPropertyTypes Passing selectedClientIds explicitly as undefined fails typecheck on this branch (TS2379), which blocks the focused test workflow before any test can run. Spread the option only when defined. * fix(update): separate ownership evidence from product applicability rea update's maintenance scope inspected only product applicability evidence, so when a FreeBuff profile was absent but REA already owned a version-pinned row in the shared ~/.agents/mcp.json, the plan omitted freebuff and left the integration stale. FreeBuff now declares its registration storage as shared, which proves ownership of an owned row but never product applicability, and maintenance requests ownership evidence through that declaration instead of reinterpreting the shared paths. Doctor and setup keep readiness evidence, foreign rows stay out of maintenance, and the Doctor exactOptionalPropertyTypes fix makes the focused test workflow runnable. * test(dotnet): split oversized operand extent diagnostics describe The describe callback reached 162 lines (max 150), failing max-lines-per-function and blocking the pre-push check for this branch. Move the single-case extent scenarios into their own describe; no test content or order changes. * fix(update): preserve ZCode's disabled shared registration during maintenance The shared user agents file doubles as ZCode's fallback, where `enable: false` disables the registration. Ownership-based maintenance read that row as a FreeBuff registration, whose format does not recognize the flag, so the row was selected and the emitted setup command rewrote it, dropping the flag and silently re-enabling a registration the user had disabled. registrationActivation now honors `enable: false` for any client whose registration storage is shared, because the activation fact binds every reader of that storage. Maintenance leaves such rows out; doctor reports them as stale, matching ZCode's own treatment. * fix(doctor): let explicit client selection authorize the config read When an ACL or an inaccessible shared parent made every access probe fail, a client selected by name was omitted before the configuration read could return its unreadable-config detail, so doctor reported it as not detected with installation remediation: an unresolved selected path collapsed to absence. An explicit selection now authorizes the read outright and the probes serve automatic discovery only. A selected client with an unreadable config reports invalid with the read failure; one with no config reports missing; automatic discovery still probes before inspecting. * fix(uninstall): share shared-storage checks between ZCode and FreeBuff clients() queued ~/.agents/mcp.json twice: once as zcode_fallback and once as freebuff. ZCode has no discoveryPaths, so its strict read still blocked uninstall on malformed shared text, despite FreeBuff's new retain-and-continue behavior. For a valid owned entry, ZCode removed it first, so FreeBuff reported skipped rather than removed. Make the shared file's checks and removal one shared decision: - Add zcodeDiscoveryPaths to ZCode so it has its own applicability evidence. - Gate zcode_fallback push on applicable, not just zcodeFallbackPath presence. - Report shared storage ownership as one decision for both clients: FreeBuff and ZCode now use clientOwnershipEvidencePaths together, so a recognizable REA-owned row proves ownership once for the shared storage, and both clients report the same result consistently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(uninstall): merge duplicated host and prove shared ownership from owned rows Uninstall.ts declared systemUninstallHost twice, preventing module load, with the exported copy returning only clients and the second copy missing clientWriteBlocker. Merge into one exported host carrying both blockers. hasOwnershipEvidence used access() existence, so an unrelated malformed ~/.agents/mcp.json established ownership and blocked every removal. Ownership now requires a readable, recognizable REA-owned row via the injected filesystem, so unrelated shared data stays retained. Also cover ZCode discoveryPaths in its path test. * fix(uninstall): keep denied product-local configurations fail-closed Unproven product applicability marked every configuration path of that client unverified, so a denied ZCode profile turned an unreadable product-local config into a retained item: uninstall continued and could report complete with REA still registered. The retain-and-continue exception now applies only to storage REA does not own, classified once by clientSharedRegistrationPaths (shared configuration plus another product's same-scope fallback). Covers the Greptile P1 on Uninstall.ts. Validation: the new test fails on the pre-fix Uninstall and passes after it; freebuff/zcode/updateMaintenance/bom/dsh suites green; clientLifecycle, clientRegistrationStatus and claudeDesktop keep the same 8 host failures as the pre-merge baseline (symlink EPERM, stale-vs-aligned on Windows). * fix(update): retain FreeBuff when ZCode reads the shared fallback Maintenance deduplicated clients on the path each inspection read, so ZCode's fallback view of ~/.agents/mcp.json marked that file "covered" and dropped FreeBuff from the scope. ZCode setup writes ~/.zcode/cli/config.json and deliberately leaves the fallback untouched (docs/client-configuration.md), so the emitted command refreshed only ZCode while the shared row both products load stayed pinned to the old package version. Each setup action rewrites only its own configuration path and no other action rewrites the shared row, so every selected client keeps its own maintenance action; the read-path covered/deduped filter is removed. Covers the Codex P2 on UpdateMaintenance.ts:104. Validation: the new regression fails on |
||
|
|
f62a2baad8 |
refactor(javascript): own coverage facts and reuse block prefixes
Separate syntax, semantic uncertainty, examination limits and observed Electron applicability at the static producer, then preserve them through worker, graph and retained/inline summary views. Derive the established parse_status from the same facts and leave historical measurements unknown. Give semantic resource-limit classifications one schema owner. Replace repeated block-prefix searches and copies with collector-scoped syntax indexes. Keep invocation environments separate, charge indexing/replay to the existing work budget and yield during prefix work. Remove the superseded synchronous collector entrypoint. Validated producer, worker, CLI/MCP, historical and partial-coverage regressions, plus actual cancellation during indexing. Bounded authored 128/256-call controls preserved all prior facts while replacing repeated search/copy work with one index pass; this is not a throughput or agent-token benchmark. |
||
|
|
f3ed1657f8 |
feat(mcp): support runtime analysis limit recovery (#7049)
* feat(mcp): support runtime analysis limit recovery * refactor(config): remove unused limit re-exports * fix(android): keep fixture release metadata dependency-free * fix(settings): preserve provider budgets and recovery facts * fix(tests): resolve lint plugins from their repository owner * refactor(mcp): verify guidance delivery without frozen wording * fix(android): align availability with runtime timeout * test(recovery): assert limit facts instead of frozen wording * fix(mcp): share runtime settings with the default JADX provider * test(mcp): bound acknowledgements and release held work on failure * fix(catalog): declare runtime settings tools as MCP-only |
||
|
|
be698d4761 | test: verify assertion contracts and the production evaluation gate | ||
|
|
760d9f6019 | fix(source-maps): retain primary failures through cleanup retries | ||
|
|
a891bb80ae |
refactor(filesystem): preserve admitted file facts
Return the validated descriptor and its original metadata from regular-file admission. Propagate that contract through owned reads, hashes, snapshots, artifact inventory and provider file workflows instead of replacing initial facts with another stat. Keep arbitrary output-handle operations separate. Preserve final descriptor/path identity proofs, borrowed-source verification, BigInt precision, cancellation provenance and failed-close ownership. Remove the obsolete source and owned-ZIP baseline stages and update their consumers and regressions. Tie read completion faults to actual reads instead of the retired duplicate stat; instrument real handles without fake handle wrappers. Validation: fresh runtime/catalog build; focused source, lifecycle, filesystem, CLI/MCP and authored provider-fixture tests; full static checks; docs checks; test discovery; duplication check. Platform-specific cases remain skipped on macOS. No installed provider or device behavior was verified. |
||
|
|
c7ae27807f |
fix(electron): retain scoped IPC registration provenance (#7031)
* fix(electron): retain scoped IPC registration provenance * fix(electron): defer mutation analysis until scoped receiver admission |
||
|
|
9df94a62cd |
feat(javascript): link assignment right-hand sides to their writes (#6206)
* feat(javascript): link assignment right-hand sides to their writes A declaration carries its value forward, but a later assignment to a variable, a property or through a compound operator stopped the forward trace at the right-hand-side read. The semantic IR now records one syntactic assignment flow per simple assignment target (ranges, operator, owning callable), and the graph projection connects each retained read of the right-hand side to the write occurrence through a defines relation. Compound assignments also consume the previous value of the target; the written value itself stays unknown, keeping the boundary of #4342 intact. Fixes #6193 * fix(javascript): preserve computed key assignment ownership * test(javascript): retain nested callback assignment ownership * docs(javascript): record assignment influence verification * test(mcp): isolate mocks and acknowledge cancellation boundaries * test(javascript): retain CLI diagnostics and current-main verification --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
d442ac752e | fix(javascript): retain completed recovery hashes on cancellation |