mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 19:23:24 +00:00
e97b6c5282a5f809db31c1ccf6891c974f3deff4
7749
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e97b6c5282 |
refactor(ci): plan change scopes through an injectable Git owner (#10804)
* refactor(ci): plan change scopes through an injectable Git owner ciChangeScope.test.ts spent about five processes per case (copy the seed repository, git add, commit and rev-parse, then node plan.mjs with its own merge-base and diff) to ask which lanes a path selects. Move the planner into change-plan.mjs as planChanges(request, repository), keep plan.mjs as the workflow entrypoint over gitRepository(), and answer the path and package-script tables from an in-memory commit. History, renames, deletions, push baselines, malformed metadata and GITHUB_OUTPUT keep the Git fixture or the spawned entrypoint. 378 tests: 30.6 s elapsed and 32.6 s CPU before, 4.0 s and 4.0 s after. * test(ci): cover workflow environment wiring through the plan entrypoint |
||
|
|
483f53fdef |
fix(electron): refuse captures handed off to an already-running app (#10989)
* fix(electron): refuse captures handed off to an already-running app When another instance holds the app's single-instance lock, Electron forwards the launch and its arguments to that instance. The active hook now stops the launched app at the refused requestSingleInstanceLock call and reports the refusal in its snapshot; the provider fails the capture with application_already_running before driving it. * fix(electron): stop pending actions on a late lock refusal and keep the final snapshot * docs(electron): describe late single-instance refusals during actions * test(electron): join the late-refusal capture even when the test fails |
||
|
|
7134053d27 |
feat(artifacts): name integrity checks for DMG, directory and release-exposure readers (#11056)
* feat(artifacts): name integrity checks for DMG, directory and release-exposure readers Directory members and release-exposure members whose file identity or bytes changed since inventory report member-identity; a directory entry without captured state reports entry-metadata and a changed directory root container-identity; an hdiutil checksum failure reports image-checksum. AnalysisArtifactChangedError carries the check from the reader failure and projects it as details.integrity_check. * fix(artifacts): name missing directory entry state and keep integrity checks through error copies * feat(artifacts): name integrity checks for ZIP, PyInstaller and changed release files (#11081) feat(artifacts): name integrity checks for ZIP, PyInstaller and changed release files, and keep them through reader projections * feat(artifacts): name integrity checks for the remaining readers and their projections (#11098) |
||
|
|
598a0c4034 |
feat(providers): let runOwned's deadline timeout carry the provider's recovery (#11089)
* feat(providers): let runOwned's deadline timeout carry the provider's recovery A deadline-caused AnalysisTimeoutError from runOwned named only the operation and its work budget, so providers whose timeouts carry their own guidance (LLDB, Hopper, Kuna, Rizin) could not adopt the deadline without losing it. runOwned now takes an optional timeoutRecovery (user message, remediation, accepted setting limit and diagnostics) and the timeout it builds carries it; its diagnostics are added to the replaced outcome's. * test(providers): report an already-elapsed budget in the recovery diagnostics test |
||
|
|
0b95e55655 |
refactor(verify): give the failure-retaining Ghidra lanes' workspaces to VerifierFixture (#11097)
The m68k, MIPS, MIPS16 shared, MIPS relocatable, PowerPC, RISC-V and DOL lanes kept their mkdtemp workspace for diagnosis whenever verification or cleanup failed, and removed it with rm after success. VerifierFixture now allocates the workspace (a plain root: Ghidra children use it as TMPDIR). Every failure branch that names the retained workspace records that reason with fixture.retain, and success releases the fixture. The verifier-fixture-root baseline shrinks by 7. |
||
|
|
5b5ca68bb3 | refactor(verify): release the agent-experience run root through VerifierFixture (#11103) | ||
|
|
144d6f959f |
fix(agentenv): record a verified teardown through the long-run release claim
#11095 called ProviderCleanupError.resolveCleanup(), which #10855 removed, so main stopped typechecking. Each retained failure's release claim already reads job membership, so clearing the jobs after a verified computer teardown is what releases them. |
||
|
|
97ffa67f84 |
refactor(setup): require the platform in client-layer readers and private-profile helpers (#11074)
* refactor(setup): require the platform in client-layer readers and private-profile helpers * refactor(setup): drop the client-layer readers' unused host import |
||
|
|
ce9bdc526a |
fix(agentenv): settle cancelled long runs and preserve teardown receipts (#11095)
Bound AgentEnv long-run cancellation, preserve partial command facts and complete computer teardown before resolving retained jobs. Includes the supervisor and cleanup implementation from #10675 plus polled-receipt and explicit-unknown exit-status fixes. Validation: 14 Python controller tests, 31 host tests and 30 compiled MCP/lifecycle tests passed. Static, documentation and discovery checks passed. Real AgentEnv deployment was not exercised: runner unavailable. Fixes #10676 Related: #10675 Co-authored-by: Adolanium <94890352+Adolanium@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
7dd24dc08c |
feat(evidence): report comparison constraints, remaining issue counts and observed workflows as fields (#11078)
* feat(evidence): report comparison-source constraints, remaining issue counts and observed workflows as fields * fix(evidence): locate snapshot bundle schema issues within the snapshot document * test(evidence): check each comparison-input mismatch and terminal omission once (#11087) |
||
|
|
de7d4dec83 | test(windows): select the Windows host through HOST_PLATFORM in the native-control capability test (#11088) | ||
|
|
b06c34031d | refactor(artifacts): take the host from HOST_PLATFORM or the caller instead of process.platform (#11090) | ||
|
|
3f88f69746 |
feat(verify): allocate kept verifier artifact directories through VerifierFixture (#11091)
The agent-client verifiers keep their lab directory as the run's artifact record (receipt, transcripts, profiles, Evidence) and name it as artifacts in the receipt, so it is not a fixture root that release should remove. VerifierFixture.keepArtifacts allocates such a directory canonically, never removes it, and names it on stderr at allocation so a run that fails before its receipt still reports where its artifacts are. The 11 client verifiers use it, and the verifier-fixture-root baseline shrinks by 11 sites. |
||
|
|
c813adb331 |
fix(verify): expect the current instruction schema to refuse the removed undecodable status (#11092)
verify-real-ghidra-com asserted that an unlisted-address record relabelled with the legacy undecodable status still parsed. #10946 removed that value with the other historical native enum values, so the lane failed on main after a correct not-in-listing result. The verifier now checks that the producer's record parses and that the relabelled record is refused. |
||
|
|
0a5df9fa32 | test(javascript): give the worker checkpoint fixture the coverage its producer always writes (#11093) | ||
|
|
c043e4e3a8 |
refactor(firmware): compose workspace and publication cleanup failures through the shared owner (#11094)
Three firmware sites built analysisErrorWithCleanupFailure(...).bindCleanupDependencies(...) by hand. They now use analysisErrorWithCleanupDependencies, which completes once the primary's and the cleanup's records both release. The phase-interruption site binds only the cleanup today; its primary is a fresh cancellation or timeout without cleanup, so the shared owner's binding is equivalent. The cleanup-dependency-binding baseline shrinks by 3. |
||
|
|
4c375b82c8 | refactor(doctor): compose system diagnostics from one host platform (#11096) | ||
|
|
382ad0343f |
refactor(sqlite): classify worker-reply read failures through the shared provider classifier (#10849)
* fix(pcap): report a refused tool launch as an unavailable tool When a capture read's tool launch was refused with EPERM, pcap reported it as unreadable tool output (AnalysisProtocolError) instead of an unavailable tool. Pcap also never told "not executable" apart from "missing". Add classifyLaunchFailure in src/process as the one owner of which spawn errnos mean missing (ENOENT, ENOTDIR) and which mean present but not executable (EACCES, EPERM, ENOEXEC, EISDIR). Pcap, apktool and gdb used three different errno lists; all three now use it. * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * refactor(process): classify Java and adb launch refusals with the shared owner (#10598) The Ghidra and JADX Java probes and adb's version probe now take missing-versus-not-executable from classifyLaunchFailure instead of their own errno checks. ELOOP and ENAMETOOLONG join the owner's missing set, so adb keeps its existing classification and both Java probes now treat a non-directory path component as a missing runtime. * fix(pcap): preserve command launch attribution * test(pcap): expect an unknown failing stage when a limited capture tool exits unsuccessfully * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * test(lint): cover baselined files in the provider-failure classifier rule * fix(apktool): report the decoder JVM's heap exhaustion as memory, not a target refusal The supervisor now watches for a managed runtime's out-of-memory report while output streams (JVM java.lang.OutOfMemoryError, V8 'JavaScript heap out of memory'), so a retention budget cannot hide it. ProviderOutcome gains a runtime-exhausted kind and classifyProviderOutcome maps it once. Apktool decode opts in and moves to the shared classifier; Ghidra's single-purpose output token becomes the JVM runtime option and its area matching reuses the shared table. * fix(process): keep the runtime's out-of-memory report on the memory error it supports * fix(pcap): attribute a limited capture's exit through the prlimit wrapper * fix(process): keep a shortened out-of-memory line marked as shortened * fix(process): identify the refused executable for every launcher shape Name the executable on errnos Node throws synchronously from spawn (ENOEXEC, ENOTDIR, ...) and read the Windows native launcher's executable-launch constraint, so pcap attributes those refusals to the selected tool or limiter instead of an unknown stage. * test(pcap): prove synchronous launch naming with ENOTDIR on every POSIX host * fix(apktool): advise the JVM limit that governs the reported memory area * fix(ghidra): read the supervisor's parsed OOM area instead of reparsing lines * fix(sqlite,capture): read V8 heap exhaustion from streamed output, not retained stderr (#10724) The SQLite worker and the Node capture decoders now declare runtime: "v8", so the supervisor observes V8's heap report as output streams. Both classifiers read the runtime-exhausted outcome instead of matching retained stderr, so a report beyond the retention budget, or one whose process then overflowed its output budget, is still reported as memory exhaustion. * refactor(evm): classify EVMole worker outcomes through the shared provider classifier (#10716) * refactor(evm): classify EVMole worker outcomes through the shared provider classifier The EVMole worker's cancellation, deadline, output budget and CPU/file-size signals now go through classifyProviderOutcome; only the prlimit launch refusal and the reserved EFBIG exit remain in its dialect. The worker is opted into V8 exhaustion scanning so a heap report names its fixed 256 MiB heap. providerOutcomeOf now reads a launch refusal only from a spawn errno, so a private-storage or carrier read errno is no longer reported as a limiter launch failure. * fix(evm): keep a stream failure's exit status and update Linux worker expectations * refactor(process): read launch refusals through the launcher identity owner * refactor(wasm): classify WABT command outcomes through the shared provider classifier (#10727) * refactor(wasm): classify WABT command outcomes through the shared provider classifier WABT's cancellation, command deadline, output budget, and inherited-limit signals now go through classifyProviderOutcome; its dialect keeps only the configuration-probe and launch-refusal unavailability and the unclassified-exit output error. A tool ended by SIGXCPU/SIGXFSZ or the memory limit is now a resource constraint instead of an output error, and a refused launch in the producer phase is reported as unavailable. The shared timeout context gains the analysis setting that selected the deadline, and the output-limit context may name its exceeded budget. * fix(wasm): keep setup guidance when a WABT version probe's output cannot be collected * refactor(providers): classify raw provider failures through one owner * refactor(process): build classified cancellations with cancelledBy and the carried caller reason * chore(lint): count runOwned's close-failure mapper from main in the classifier baseline * fix(process): carry the runtime's exhaustion report on every memory error that claims it SQLite and historical-capture memory errors recognised a streamed V8 heap report but dropped it, so a report outside retained output reached callers without its source line or omission flags. One projection, runtimeExhaustionReport, now owns that shape for the shared classifier and both consumers. Also lowers the EVMole and WABT cancellation-constructor baselines. * fix(process): keep the provider's recovery for a native-thread exhaustion report The shared classifier replaced the provider-supplied recovery with generic capacity advice whenever the JVM reported it could not create a native thread, dropping Apktool's launcher guidance and flipping retryable to true. The provider's recovery now wins; the capacity advice remains the fallback for providers that supply none. * refactor(pwntools): classify pwntools failures through the shared provider classifier (#10782) * refactor(pwntools): classify pwntools failures through the shared provider classifier pwntools' per-site classifier is replaced by pwntoolsFailureDialect for classifyProviderFailure. Command outcomes go through classifyProviderOutcome, launch refusals through launcherRefusalOf instead of a 'spawn ' syscall prefix check, the input limit through the file dialect's fileSize, and the cleanup report through commandCleanup. The shared read cancellation now carries the reader's partial observation, and resource-signal reports accept provider detail. * fix(pwntools): report a failed command's output once and expect resource_constraint for overflow The shared outcome owner already attaches the command's output as capturedOutput, so the pwntools adapter fallback no longer copies the same text into diagnostics.stdout, diagnostics.stderr and diagnostics.captured_output; diagnostics keep the exit facts. Update the overflow expectations the dialect migration missed (layout provider cleanup and over-budget rows, pwntools cleanup) to resource_constraint. * refactor(wasm): leave WABT cancellation to the shared owners WabtFailures matched any Error named AbortError as a cancellation. No WABT path produces one: reads, path checks and owned commands report cancellation as ArtifactReaderFailure or OwnedCommandFailure, which classifyProviderFailure and classifyProviderOutcome already classify with the caller's reason. The provider's two signal checks now build the cancellation with cancelledBy. Lowers the AnalysisCancelledError constructor baseline for both WABT files to zero. * fix(wasm): report a cancelled snapshot write as the caller's cancellation The private snapshot write passed the caller's signal to Node's writeFile, whose abort envelope reached the dialect's unclassified output failure once the name-based AbortError guess was removed. The write now turns the envelope carrying its own signal's reason into cancelledBy at the producer. * refactor(firmware): classify firmware failures through the shared provider classifier (#10810) Firmware producers now report their own deadline expiry: the start check, the output inventory and launcher admission throw the phase timeout where they observe the abort, and a read the phase signal cancelled reports it through the dialect's interruption. The classifier no longer rereads a cancellation's reason as a timeout. A new readCleanup hook keeps firmware's cleanup report shape. * refactor(captures): classify TShark, sigrok and pcap failures through the shared provider classifier TsharkCaptureProvider and SigrokRecordingProvider replace #failure with a dialect, and PcapProvider replaces analysisFailure and the tool-identity classifier. ArtifactAnalysisResources exposes its command context and a readCleanupFailure composer so the readCleanup hook keeps each provider's cleanup report shape. * refactor(jeb): classify JEB failures through the shared provider classifier JEB's raw MCP failures go through classifyProviderFailure with a JEB dialect; a typed attribution step reports a shared phase's failure under the REA operation. Each MCP phase deadline now reports its own interruption when it aborts, deciding a cancellation's owner from the caller's own signal instead of comparing abort reasons. A refusal carrying the JVM's OutOfMemoryError report becomes a resource constraint naming JEB's Java heap. * fix(jeb): advise the JVM limit that governs the reported memory area * refactor(ghidra): classify Ghidra failures through the shared provider classifier PSP extension inspection reports through classifyProviderFailure with a Ghidra dialect. The startup deadline decides at abort time whether the shared startup owner closed it, so Ghidra and Hopper no longer compare the abort reason with the owner's sentinel, and Ghidra's startup no longer compares a producer cancellation's reason with the deadline's. Three helpers that only construct one error kind now name that kind instead of AnalysisError. * refactor(hopper): classify original-source read failures through the shared provider classifier (#10838) * test(ghidra): pin the aborted startup deadline over a producer cancellation * refactor(kuna): classify Kuna failures through the shared provider classifier Session operations, the workspace copy and the project export report raw failures through classifyProviderFailure with Kuna dialects; the copy and export keep their cleanup report shapes through the readCleanup hook. * refactor(adb): report a pulled file's digest failure from its own type * refactor(sqlite): classify worker-reply read failures through the shared provider classifier * refactor(ghidra): classify Ghidra failures through the shared provider classifier (#10836) * refactor(ghidra): classify Ghidra failures through the shared provider classifier PSP extension inspection reports through classifyProviderFailure with a Ghidra dialect. The startup deadline decides at abort time whether the shared startup owner closed it, so Ghidra and Hopper no longer compare the abort reason with the owner's sentinel, and Ghidra's startup no longer compares a producer cancellation's reason with the deadline's. Three helpers that only construct one error kind now name that kind instead of AnalysisError. * refactor(hopper): classify original-source read failures through the shared provider classifier (#10838) * test(ghidra): pin the aborted startup deadline over a producer cancellation * refactor(kuna): classify Kuna failures through the shared provider classifier (#10843) Session operations, the workspace copy and the project export report raw failures through classifyProviderFailure with Kuna dialects; the copy and export keep their cleanup report shapes through the readCleanup hook. * chore(guards): shrink the cancellation construction baseline after merging the base * refactor(ida): classify IDA operation failures through the shared provider classifier (#10859) * refactor(ida): classify IDA operation failures through the shared provider classifier * refactor(process): let artifact-resource consumers classify through the shared provider classifier (#10867) * test(providers): pin attribution of a cleanup-failed read's typed primary |
||
|
|
df1e647266 |
refactor(desktop): let build-computer and agentenv cleanup errors read their owner's release (#10855)
* refactor(errors): read cleanup completion from dependencies instead of pushing it to dependents AnalysisError.cleanupIncomplete becomes a getter over the error's own unresolved state and its bound dependencies. The WeakRef dependents graph and resolveCleanup's push propagation are removed, and subclasses mark their initial state through markCleanupIncomplete instead of overriding a public mutable field. * fix(errors): settle bound dependencies before binding more A composite whose dependencies had released but whose status was never read stayed incomplete when a later dependency was bound. * refactor(errors): let errors read a lease group's release instead of resolving them (#10759) AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink (#10763) * refactor(errors): let errors read a lease group's release instead of resolving them AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink * refactor(process): let worker cleanup errors read their root epoch's release OwnedWorkerRuntime's root epoch is now an AnalysisCleanupReleaseClaim. Errors bound to it read its release when asked instead of the epoch pushing resolveCleanup() through weak references, and a runtime without a retained root binds an already-released owner. Removes the OwnedWorkerCleanupFailure structural type and four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(pcap): let pcap cleanup errors read command and snapshot release (#10792) Retained pcap commands, retained snapshot failures and snapshot completion descriptors now own their release and errors read it: commands and snapshot failures implement AnalysisCleanupReleaseClaim, and a failed completion-descriptor close is retried through an AnalysisCleanupLease bound to its error. Removes four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(process): let Darwin helper cleanup errors read their owner's release Darwin helper cache and run-token reader root cleanup now record an AnalysisCleanupRelease that every failure reports; a successful retry confirms it. Replaces the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes two resolveCleanup() and two bindCleanupDependencies() calls; both counted baselines shrink. * refactor(ghidra): let Ghidra cleanup errors read the client's and checkpoint's release GhidraClient and GhidraCheckpoint bind each cleanup failure to an AnalysisCleanupRelease and confirm it when a later close or retry releases everything, instead of keeping a set of failures and pushing resolveCleanup() to each. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(process): let debugger session cleanup errors read a confirmed stop OwnedDebuggerSessionRegistry binds each retained gdb or rizin cleanup failure to the session's AnalysisCleanupRelease and confirms it when a stop is confirmed, keeping the latest failure for retry reporting, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): drop the debugger registry's unused closeOperation option Returning the latest retained failure removed the last reader of closeOperation; remove the option and the values gdb and rizin supplied. * refactor(server): let environment shutdown errors read a successful close serveEnvironment binds each shutdown failure to an AnalysisCleanupRelease that a later successful close confirms, instead of pushing resolveCleanup() to a set of failures. The state-file retry test now also requires the earlier report to read the release. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): release retained screen-judge cleanup through its lease Each retained judge or screenshot cleanup owner is wrapped in an AnalysisCleanupLease bound to its failure; close() releases the lease, which records the release the failure reads, instead of closing the owner and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(ida): let IDA close failures read the session's later close IdaSessionClient's close failure binds an owner that is both its resource owner and its release claim, read from the client's closed state, instead of keeping weak references and pushing resolveCleanup() after a successful retry. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(javascript): let source-map codec cleanup errors read a later close (#10814) * refactor(javascript): let source-map codec cleanup errors read a later close OwnedCodec binds each close failure to an AnalysisCleanupRelease that a later successful close confirms, replacing the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes one resolveCleanup() and one bindCleanupDependencies() call; both counted baselines shrink. * refactor(cutter): let pending Cutter command errors read the completion receipt (#10815) * refactor(cutter): let pending Cutter command errors read the completion receipt Each pending Cutter command keeps an AnalysisCleanupRelease bound to its timeout failure; the producer's terminal completion receipt confirms it instead of pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(application): let provider candidate cleanup errors read the candidate's close (#10817) * refactor(application): let provider candidate cleanup errors read the candidate's close AnalysisProviderRegistry keeps one AnalysisCleanupRelease per candidate whose resource close is unconfirmed; failures bind to it and a later confirmed close confirms it, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * fix(errors): bind a cleanup release claim to an error at most once AnalysisError kept release claims in an array, so a provider whose retried close returned the same error bound the same claim again on every retry and each cleanupIncomplete read scanned the duplicates. Keep the claims in a set. * refactor(application): let reverse-tool cleanup errors read a verified stop (#10819) * refactor(application): let reverse-tool cleanup errors read a verified stop Each retained provider process group in ReverseEngineeringService keeps an AnalysisCleanupRelease; its command and retry failures bind to it and a later verified stop confirms it, instead of collecting failures and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(sqlite): let SQLite worker and root cleanup errors read their release (#10821) Each retained SQLite snapshot cleanup records an AnalysisCleanupRelease for its worker and for its runtime root; the resource failures bind to them and a verified stop or root removal confirms them, instead of pushing resolveCleanup(). Composite failures keep reading those resource failures. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(android): let JADX cleanup errors read their retained cleanup's release Each retained JADX cleanup records an AnalysisCleanupRelease for the admission failure's descriptor owners and one for the whole retained cleanup. The admission failure and every error the cleanup reports bind to them, and a confirmed close confirms them, instead of pushing resolveCleanup() through WeakRefs to reported errors. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let session close failures read the client's later close A retained session cleanup records an AnalysisCleanupRelease; unowned cleanup failures the client's close reported bind to it and the successful close confirms it, instead of the session collecting them and pushing resolveCleanup(). Failures that already follow their own owner keep reading it. Adds a regression for an unowned close failure. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): let build-computer and agentenv cleanup errors read their owner's release Build-computer teardown, retained task readers, remote reader folders and agentenv solve sandboxes each record an AnalysisCleanupRelease that their bound failures read; a verified teardown or stop confirms it instead of pushing resolveCleanup() through WeakRef sets. Long-run job failures read whether every job they name has confirmed its stop, so a failure naming two jobs no longer reads complete when only one stops (regression added). WeakRef sets kept only where late facts (completion receipts, reader views) are still retained as diagnostics. Removes six resolveCleanup() calls; the counted baseline shrinks. * refactor(kuna): let source-map and Kuna cache cleanup errors read their owner's release (#10856) * refactor(browser): let late source-map fetch errors read their response's release A pending source-map fetch and a response cancellation each record an AnalysisCleanupRelease that their cancellation or deadline failure reads; releasing the late response or the reader lock confirms it instead of pushing resolveCleanup(). Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(kuna): let project-cache cleanup errors read each owner's release Each retained Kuna resource owner (process, staging, hash descriptor, retired file) records a release that the errors reporting it read; an error completes once every owner it reports confirms, and retirement that moves staging to a retained file forwards the staging owner's release to the file's. Replaces the WeakRef report list, its pruning and the resolveCleanup() push. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): forbid resolveCleanup() pushes; native markers read their supervisor's release (#10857) * refactor(providers): let an attributed client failure read its source's completed cleanup Re-attributing a failure whose source cleanup already completed now binds a claim reading that source's release instead of pushing resolveCleanup() onto the new error; a pending source is still bound as a dependency. Resources stay as history, as before. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): let native command markers read their supervisor's release ProviderProcessSupervisor records an AnalysisCleanupRelease that a stop proving the process ended confirms. Native command and LLDB resolver cleanup markers bind to their supervisor's release, so a verified stop by either owner completes them, instead of each owner pushing resolveCleanup() onto the markers it tracks. Removes the last two resolveCleanup() calls outside the error base; the counted baseline is empty. * chore(verify): forbid resolveCleanup() pushes outside the error base Every production owner now confirms a release its errors read, so the counted baseline is empty. The guard becomes an outright ban with no baseline entry. * test(native): complete native command and LLDB markers through a direct supervisor stop * refactor(errors): complete an error's cleanup from its owner's record and every dependency (#10892) * refactor(errors): complete an error's cleanup from its owner's record and every dependency * refactor(errors): complete test errors through an owner release and delete resolveCleanup() (#10898) * refactor(android): compose JADX and Apktool cleanup failures through one shared owner (#10900) * refactor(android): compose JADX and Apktool cleanup failures through one shared owner * refactor(application): compose service cleanup failures through the shared owner (#10902) |
||
|
|
7826e9688d |
refactor(reverse): fake objdump and Rizin commands only through the owned supervisor (#11076)
* refactor(reverse): fake objdump and Rizin commands only through the owned supervisor * test(reverse): fake launch refusals and failed exits as the owned supervisor reports them * refactor(reverse): name objdump and Rizin command repairs through the command port (#11080) |
||
|
|
12a0f4a94f | fix(il2cpp): read ELF hash-table words through BinaryReader (#11083) | ||
|
|
29dd58c96d |
fix(il2cpp): resolve ELF ABS64 and GLOB_DAT image definitions (#11075)
Derive bounded ELF ABS64 and GLOB_DAT link-image values for IL2CPP module scanning while preserving the default conservative relocation policy. Retain ambiguous hash declarations, validate complete hash-table mappings, and disclose runtime-binding limitations in CLI and MCP evidence. Validation: 408 focused tests, check:fast and docs:check passed. Public CLI/MCP and independently linked ARM64/x86-64 ELF arithmetic were checked; the original Unity binaries remain unavailable. Refs #10478 Related: #10495 Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
cabd56ea71 |
refactor(domain): give strict UTF-8 decoding one owner with an explicit BOM policy (#10728)
* refactor(domain): give strict UTF-8 decoding one owner with an explicit BOM policy * fix(domain): keep the leading-BOM behaviour every migrated UTF-8 decoder had * refactor(domain): read the domain layer's strict UTF-8 through the BOM-policy owner (#10803) Twelve domain decoders built their own fatal TextDecoder with ignoreBOM: true. They now use strictUtf8Decoder("preserve"), which keeps that behaviour: each reads bytes where a leading U+FEFF is content (binary-format names and fields, JSON and XML read byte-for-byte, recorded bodies, registry seeds whose kept bytes are re-emitted). The counted baseline drops from 74 to 62. * refactor(artifacts): read artifact readers' strict UTF-8 through the BOM-policy owner (#10871) Fourteen artifact reader modules (17 sites) built their own fatal TextDecoder. They now take it from strictUtf8Decoder with the policy each had: every one kept a leading BOM (ignoreBOM: true), so they use "preserve"; JavaScriptArtifactFiles keeps it for JavaScript and HTML entries and strips it otherwise, as before. The strict-utf8-decoder baseline drops those 17 sites. * refactor(domain): drop TextDecoder imports left by the strict UTF-8 migration * refactor(application): read MCP registration metadata through the strict UTF-8 owner * refactor(formats): read binary-format readers' strict UTF-8 through the BOM-policy owner (#10903) * refactor(formats): read binary-format readers' strict UTF-8 through the BOM-policy owner * refactor(formats): drop the model readers' unused TextDecoder imports * refactor(browser): read browser capture and fetch strict UTF-8 through the BOM-policy owner (#10935) * refactor(browser): read browser capture and fetch strict UTF-8 through the BOM-policy owner * refactor(native): read LLDB and Mach-O name strict UTF-8 through the BOM-policy owner (#10936) * refactor(native): read LLDB and Mach-O name strict UTF-8 through the BOM-policy owner * refactor(process): read MCP and NDJSON transport frames' strict UTF-8 through the BOM-policy owner (#10937) * refactor(process): read MCP and NDJSON transport frames' strict UTF-8 through the BOM-policy owner * refactor(application): read JSON and file inputs' strict UTF-8 through the BOM-policy owner (#10938) * refactor(application): read JSON and file inputs' strict UTF-8 through the BOM-policy owner * refactor(providers): read IDA, Electron, Ghidra and reference strict UTF-8 through the BOM-policy owner (#10939) * refactor(providers): read IDA, Electron, Ghidra and reference strict UTF-8 through the BOM-policy owner * refactor(evm): read the hex bytecode carrier's strict UTF-8 through the owner and refuse new local decoders (#10940) * refactor(evm): read the hex bytecode carrier's strict UTF-8 through the BOM-policy owner * chore(architecture): match local strict UTF-8 decoders in any option order |
||
|
|
abd36dd250 |
refactor(browser): parse Runtime and Debugger events once by registered schemas (#10742)
* refactor(browser): parse frame lifecycle events once by a registered event schema CdpConnection admits each event through protocol/CdpEvents.ts, which parses the five Page frame lifecycle events once into identity facts plus a frame URL observation, like a frame-tree node. Screenshot, page capture, the observation timeline, WebMCP, Electron inspection and the execution window read those facts instead of re-parsing the raw payload; CdpFrameFacts no longer carries the raw source record. Playwright CDP session subscriptions name an event from Playwright's protocol table, and an architecture guard counts the remaining raw event payload reads so they can only shrink. * refactor(browser): parse Runtime and Debugger events once by registered schemas Register Debugger.scriptParsed, Debugger.scriptFailedToParse, Runtime.executionContextCreated, Runtime.executionContextDestroyed and Runtime.consoleAPICalled. Script and context payloads carry both the tolerant facts passive capture uses and the active runtime's strict declaration, derived from one parse, plus the declaration's byte size for the runtime retention budget. Page capture, Electron script capture, the V8 Inspector provider and the runtime source inventory now read the registered payload. The cdp-raw-event-params baseline drops from 20 to 7. * refactor(browser): admit transport events through the registered-event owner Remove the unused cdpFrameUrl wrapper; its fragment cases now exercise observeCdpFrameUrl. Add a connection-level test that two subscribers share one parsed payload and the raw params. * fix(browser): report an unserializable event declaration's size instead of throwing JSON.stringify can throw on a declaration JSON.parse accepted (nesting deeper than the serializer's stack). The registry sized script and context declarations inside the connection's WebSocket callback, so such an event escaped as an uncaught exception. The size is now a Result; the runtime source inventory raises the failure inside its own catch, as before. * refactor(browser): parse Network events once by registered schemas (#10743) * refactor(browser): parse Network events once by registered schemas Register Network.requestWillBeSent, responseReceived, loadingFinished, loadingFailed, webSocketCreated and webSocketFrameSent/Received. The request payload carries the tolerant facts page capture and the timeline read plus the active runtime's strict declaration. Page capture's network and WebSocket handlers, the timeline's request tracking and the runtime request inventory now read the registered payload. The cdp-raw-event-params baseline drops from 7 to 5. * refactor(browser): drop payload helpers the capture handlers no longer use * refactor(browser): read every CDP event payload through the registry (#10745) * refactor(browser): read every CDP event payload through the registry Register Target.attachedToTarget, Target.detachedFromTarget, Page.lifecycleEvent and WebMCP.toolsAdded/toolsRemoved, and carry a requested navigation's reason and a commit's transition type in the frame-event payload. The timeline no longer threads raw params into its entries: each entry receives its timestamp, frame and loader identity explicitly. WebMCP discovery, the service-worker policy blocker and the target-event matcher read the registered payload. With no raw reads left, the cdp-raw-event-params guard is enforced at zero instead of counted. * refactor(browser): drop raw payload helpers the timeline and worker blocker no longer use * refactor(browser): type Playwright CDP session events by the registry (#10751) PlaywrightCdpSession.on subscribes only to registered events and hands the listener the payload parsed by its registered schema, returning the unsubscribe function. Private storage seeding reads registered payloads, including the events of non-flat child sessions, and applies its strict seeding policy to the parsed facts. Its local attach, detach, nested message and pause schemas and the storage-only script/context schemas are removed; Debugger.paused, Runtime.executionContextsCleared and Target.receivedMessageFromTarget join the registry. * test(browser): admit fake policy events through the event registry The service-worker policy now reads event.registered, but the PlaywrightScenarioSession fake connection delivered raw events, so three detached-target tests never reached the policy. The fake now admits each event with receiveCdpEvent as CdpConnection does. * fix(browser): fail the CDP session closed when an event listener throws (#10758) * fix(browser): fail the CDP session closed when an event listener throws An exception from a CDP event subscriber escaped CdpTransportCore's socket message callback uncaught (for example the service-worker blocker's protocol_error on a Target event without a sessionId). The transport now stops delivery, fails the connection as a protocol error whose cause is the listener's exception, rejects pending and later commands with it, and notifies protocol-failure subscribers. The Playwright CDP session relay applies the same rule to its event listeners. * fix(browser): report a failed service-worker policy connection at the next policy check The policy's event listener rejects a malformed Target event, which now fails its connection. With no policy command pending, nothing reported it and later iframe targets went unprotected. The policy records its connection's protocol failure and assertBlocked, run before each scenario step, rethrows it. * fix(browser): keep cleanup commands available after a listener failure A listener failure no longer marks the wire as broken. The transport still rejects pending commands, notifies protocol-failure subscribers, stops delivering events and refuses reuse, but it keeps reading replies and admits commands sent in cleanup grace. The service-worker policy can then remove its init scripts, restore the main realm, detach and release its socket. Wire-level protocol errors still refuse every later command. The PlaywrightScenarioSession policy fake gains onProtocolFailure, which the policy now subscribes to. * refactor(browser): keep raw CDP event payloads out of the received event (#10764) * refactor(browser): keep raw CDP event payloads out of the received event CdpReceivedEvent and CdpTransportEvent no longer carry params: receiveCdpEvent hands the raw payload only to the registered schema, so a subscriber cannot read it by property access, destructuring or computed keys. This supersedes the event.params text guard in architecture-guards, which is removed. * refactor(browser): read registered event payloads in the JavaScript verifiers The runtime, storage and URL-userinfo verifiers subscribe to CdpConnection, which no longer hands subscribers raw params. They now read event.registered. A test scans every scripts/ onEvent callback for raw payload reads, since the TypeScript check does not cover them. The storage verifier's pause trace records a malformed pause instead of the unregistered reason member. * refactor(browser): track the timeline's main frame with the document tracker (#10779) TimelineCapture kept its own mutable main frame id and replaced it on a root replacement. It now holds the CdpDocumentTracker that CdpTargetSession owns and observes the replacement document through it; every main-frame check (lifecycle, navigation, document request, redirect) reads the tracker's current frame. A characterization test pins that the replaced root's lifecycle events are no longer recorded. * refactor(browser): select CDP events only by their registered name (#10829) CdpReceivedEvent carried the wire method as a plain string, so a subscriber could compare it with a misspelt or unregistered name and the check compiled but never matched. Three owners selected Inspector.targetCrashed, an unregistered event, that way. Register Inspector.targetCrashed and drop the wire method from the received event. Subscribers select events by registered.method, whose type is the registered event names. The capture coverage start keeps reading the wire domain, now the event's domain field. * fix(browser): retire a policy child session that CDP reports gone After a listener failure the connection stops delivering events, so an iframe's Target.detachedFromTarget never retires its policy target. Cleanup then sent Page.removeScriptToEvaluateOnNewDocument to the dead session, kept the stale child, and every retry failed before detaching the root. The service-worker policy owner now treats CDP's session-not-found rejection as proof that the child is gone and retires it. The classifier moves from CdpTargetSession to CdpCommandRejection, its owner, and the target-session detach path uses the same one. * refactor(browser): route target events through one session owner (#10835) * refactor(browser): route target events through one session owner Page capture, WebMCP discovery, screenshot capture and the runtime sources each compared the envelope session ID themselves, while the observation window and execution collection used cdpTargetEventMatches, which also routes the root Target.detachedFromTarget that names the target's session. onCdpTargetEvent in CdpTargetEvents.ts now subscribes every target consumer with that one rule; the matcher is private and the per-subscriber comparisons are removed. Electron inspection keeps its own filter while its capture isolation awaits a maintainer decision. * fix(browser): report WebMCP subframe tools whose document is unverified (#10839) * fix(browser): report WebMCP subframe tools whose document is unverified A committed subframe navigation kept the frame's tools silently when CDP reported no loader at the same URL, and removed them on any URL change even when the loader proved the same document. Each frame now carries a CdpDocumentTracker, the session's document identity owner. Only a proven change removes the frame's tools. An unknown comparison keeps them visible, marks webmcp_tools attach-limited and names the frames whose document identity could not be established. * test(browser): prove an unverified live subframe limits WebMCP coverage * fix(browser): key a WebMCP registration by its frame and tool name A subframe tool kept across a committed navigation that changed the URL but not the loader was stored under a key built from the old URL, so a later toolsAdded for the same frame and name added a second entry. Registrations are now keyed by frame and name; tool_key still records the registering frame URL. * test(browser): deliver fake CDP events through the transport's admission (#10840) Event fakes each rebuilt the received event: CdpAgentHints typed its listeners as raw wire events behind an unknown cast, and the Electron, scenario-session and routing tests each wrapped receiveCdpEvent by hand. fakeCdpEvents (tests/fixtures) is a CdpConnection.onEvent fake whose emit admits each raw event with receiveCdpEvent and the wire byte count, so a change to the received event shape fails at the fake instead of silently not exercising subscribers. * refactor(browser): own the selected page generation in one target document tracker (#10860) * refactor(browser): own the selected page generation in one target document tracker Page capture, screenshot, the observation window, the runtime session and the execution window each built a document tracker or rule of their own from root-frame navigation events. CdpTargetDocument now follows the target session's root-frame events and the frame-tree replies its consumers read, classifies root identity once, and reports each navigation to consumers that decide only what it means for their evidence. * fix(browser): report a lost scenario policy connection before the next step (#10864) * fix(browser): report a lost scenario policy connection before the next step The service-worker policy recorded only protocol failures. When its CDP socket closed or its page session detached, later documents lost the blocking script, but the scenario learned of it only when a frame check found an unprotected realm. The owner now records the disconnect or detach when CDP reports it; the next policy check and the next step's action report it first. * fix(browser): refuse an unregistered CDP command before it reaches the browser (#10868) JavaScript verifiers can name any command, and the send owners refused an unregistered one only when its reply arrived, after the browser had acted on it. CdpConnection and the Playwright session now refuse the name before sending, and the Playwright session refuses an unregistered event name instead of subscribing to events no listener receives. The verifier text scan stays as an early warning and documents what it cannot see. * fix(browser): keep a proven root change and the loaderless selection's uncertainty Two review findings on the target document owner. A root event naming another frame with a malformed loader set `changed` but was announced as unidentified, so the execution window failed with protocol_error and dropped what it had collected; the owner now announces it as the proven change it is. The runtime session compared each frame-tree reply with the tracker's current document, which can learn a loader from an event, so a loaderless selection followed by an event and a reply with that loader compared as same; it now compares the reply with the selected document through the owner, and reports target_changed as before. * test(browser): refuse the next scenario step after the policy session detaches * refactor(browser): read WebMCP document identity from the target document owner (#10884) * refactor(browser): read WebMCP document identity from the target document owner WebMCP discovery compared the first and last frame-tree roots itself and kept a document tracker per subframe. CdpTargetDocument now follows the selected root and each committed subframe for it: the final frame tree feeds the owner, a root change proven by a navigation event during discovery is target_changed as in page capture, and a subframe whose committed document changed loses its tools. A subframe navigation without a loader still keeps the tools and reports them as unverified. * fix(browser): start a subframe first seen within its document with an unknown loader A subframe absent from the initial frame tree and first seen through Page.navigatedWithinDocument had no document tracker, so a later commit started a fresh one and the tools it registered meanwhile lost the unverified-document limitation. The owner now starts such a subframe with an unknown loader. * fix(browser): refuse a verifier's unregistered CDP event name at subscription (#10885) JavaScript verifiers subscribed to every event with CdpConnection.onEvent and compared registered.method with a string literal. A misspelt or unregistered name never matched and the verifier waited until its timeout. CdpConnection.onRegisteredEvent now takes one event name, refuses an unregistered one before subscribing (the same registry check the Playwright session applies), and hands the listener only that event's registered parse. The verifiers subscribe only through it, and the evaluation test rejects a raw onEvent subscription in scripts. * fix(browser): keep subframe documents by frame and loader without their URLs |
||
|
|
b98fbdc442 |
refactor(ida): let IDA close failures read the session's later close (#10811)
* refactor(errors): read cleanup completion from dependencies instead of pushing it to dependents AnalysisError.cleanupIncomplete becomes a getter over the error's own unresolved state and its bound dependencies. The WeakRef dependents graph and resolveCleanup's push propagation are removed, and subclasses mark their initial state through markCleanupIncomplete instead of overriding a public mutable field. * fix(errors): settle bound dependencies before binding more A composite whose dependencies had released but whose status was never read stayed incomplete when a later dependency was bound. * refactor(errors): let errors read a lease group's release instead of resolving them (#10759) AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink (#10763) * refactor(errors): let errors read a lease group's release instead of resolving them AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink * refactor(process): let worker cleanup errors read their root epoch's release OwnedWorkerRuntime's root epoch is now an AnalysisCleanupReleaseClaim. Errors bound to it read its release when asked instead of the epoch pushing resolveCleanup() through weak references, and a runtime without a retained root binds an already-released owner. Removes the OwnedWorkerCleanupFailure structural type and four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(pcap): let pcap cleanup errors read command and snapshot release (#10792) Retained pcap commands, retained snapshot failures and snapshot completion descriptors now own their release and errors read it: commands and snapshot failures implement AnalysisCleanupReleaseClaim, and a failed completion-descriptor close is retried through an AnalysisCleanupLease bound to its error. Removes four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(process): let Darwin helper cleanup errors read their owner's release Darwin helper cache and run-token reader root cleanup now record an AnalysisCleanupRelease that every failure reports; a successful retry confirms it. Replaces the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes two resolveCleanup() and two bindCleanupDependencies() calls; both counted baselines shrink. * refactor(ghidra): let Ghidra cleanup errors read the client's and checkpoint's release GhidraClient and GhidraCheckpoint bind each cleanup failure to an AnalysisCleanupRelease and confirm it when a later close or retry releases everything, instead of keeping a set of failures and pushing resolveCleanup() to each. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(process): let debugger session cleanup errors read a confirmed stop OwnedDebuggerSessionRegistry binds each retained gdb or rizin cleanup failure to the session's AnalysisCleanupRelease and confirms it when a stop is confirmed, keeping the latest failure for retry reporting, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): drop the debugger registry's unused closeOperation option Returning the latest retained failure removed the last reader of closeOperation; remove the option and the values gdb and rizin supplied. * refactor(server): let environment shutdown errors read a successful close serveEnvironment binds each shutdown failure to an AnalysisCleanupRelease that a later successful close confirms, instead of pushing resolveCleanup() to a set of failures. The state-file retry test now also requires the earlier report to read the release. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): release retained screen-judge cleanup through its lease Each retained judge or screenshot cleanup owner is wrapped in an AnalysisCleanupLease bound to its failure; close() releases the lease, which records the release the failure reads, instead of closing the owner and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(ida): let IDA close failures read the session's later close IdaSessionClient's close failure binds an owner that is both its resource owner and its release claim, read from the client's closed state, instead of keeping weak references and pushing resolveCleanup() after a successful retry. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(javascript): let source-map codec cleanup errors read a later close (#10814) * refactor(javascript): let source-map codec cleanup errors read a later close OwnedCodec binds each close failure to an AnalysisCleanupRelease that a later successful close confirms, replacing the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes one resolveCleanup() and one bindCleanupDependencies() call; both counted baselines shrink. * refactor(cutter): let pending Cutter command errors read the completion receipt (#10815) * refactor(cutter): let pending Cutter command errors read the completion receipt Each pending Cutter command keeps an AnalysisCleanupRelease bound to its timeout failure; the producer's terminal completion receipt confirms it instead of pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(application): let provider candidate cleanup errors read the candidate's close (#10817) * refactor(application): let provider candidate cleanup errors read the candidate's close AnalysisProviderRegistry keeps one AnalysisCleanupRelease per candidate whose resource close is unconfirmed; failures bind to it and a later confirmed close confirms it, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * fix(errors): bind a cleanup release claim to an error at most once AnalysisError kept release claims in an array, so a provider whose retried close returned the same error bound the same claim again on every retry and each cleanupIncomplete read scanned the duplicates. Keep the claims in a set. * refactor(application): let reverse-tool cleanup errors read a verified stop (#10819) * refactor(application): let reverse-tool cleanup errors read a verified stop Each retained provider process group in ReverseEngineeringService keeps an AnalysisCleanupRelease; its command and retry failures bind to it and a later verified stop confirms it, instead of collecting failures and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(sqlite): let SQLite worker and root cleanup errors read their release (#10821) Each retained SQLite snapshot cleanup records an AnalysisCleanupRelease for its worker and for its runtime root; the resource failures bind to them and a verified stop or root removal confirms them, instead of pushing resolveCleanup(). Composite failures keep reading those resource failures. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let JADX and session close failures read their owner's release (#10854) * refactor(android): let JADX cleanup errors read their retained cleanup's release Each retained JADX cleanup records an AnalysisCleanupRelease for the admission failure's descriptor owners and one for the whole retained cleanup. The admission failure and every error the cleanup reports bind to them, and a confirmed close confirms them, instead of pushing resolveCleanup() through WeakRefs to reported errors. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let session close failures read the client's later close A retained session cleanup records an AnalysisCleanupRelease; unowned cleanup failures the client's close reported bind to it and the successful close confirms it, instead of the session collecting them and pushing resolveCleanup(). Failures that already follow their own owner keep reading it. Adds a regression for an unowned close failure. Removes one resolveCleanup() call; the counted baseline shrinks. |
||
|
|
d22da738d5 |
refactor(adb): report a pulled file's digest failure from its own type (#10848)
* fix(pcap): report a refused tool launch as an unavailable tool When a capture read's tool launch was refused with EPERM, pcap reported it as unreadable tool output (AnalysisProtocolError) instead of an unavailable tool. Pcap also never told "not executable" apart from "missing". Add classifyLaunchFailure in src/process as the one owner of which spawn errnos mean missing (ENOENT, ENOTDIR) and which mean present but not executable (EACCES, EPERM, ENOEXEC, EISDIR). Pcap, apktool and gdb used three different errno lists; all three now use it. * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * refactor(process): classify Java and adb launch refusals with the shared owner (#10598) The Ghidra and JADX Java probes and adb's version probe now take missing-versus-not-executable from classifyLaunchFailure instead of their own errno checks. ELOOP and ENAMETOOLONG join the owner's missing set, so adb keeps its existing classification and both Java probes now treat a non-directory path component as a missing runtime. * fix(pcap): preserve command launch attribution * test(pcap): expect an unknown failing stage when a limited capture tool exits unsuccessfully * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * test(lint): cover baselined files in the provider-failure classifier rule * fix(apktool): report the decoder JVM's heap exhaustion as memory, not a target refusal The supervisor now watches for a managed runtime's out-of-memory report while output streams (JVM java.lang.OutOfMemoryError, V8 'JavaScript heap out of memory'), so a retention budget cannot hide it. ProviderOutcome gains a runtime-exhausted kind and classifyProviderOutcome maps it once. Apktool decode opts in and moves to the shared classifier; Ghidra's single-purpose output token becomes the JVM runtime option and its area matching reuses the shared table. * fix(process): keep the runtime's out-of-memory report on the memory error it supports * fix(pcap): attribute a limited capture's exit through the prlimit wrapper * fix(process): keep a shortened out-of-memory line marked as shortened * fix(process): identify the refused executable for every launcher shape Name the executable on errnos Node throws synchronously from spawn (ENOEXEC, ENOTDIR, ...) and read the Windows native launcher's executable-launch constraint, so pcap attributes those refusals to the selected tool or limiter instead of an unknown stage. * test(pcap): prove synchronous launch naming with ENOTDIR on every POSIX host * fix(apktool): advise the JVM limit that governs the reported memory area * fix(ghidra): read the supervisor's parsed OOM area instead of reparsing lines * fix(sqlite,capture): read V8 heap exhaustion from streamed output, not retained stderr (#10724) The SQLite worker and the Node capture decoders now declare runtime: "v8", so the supervisor observes V8's heap report as output streams. Both classifiers read the runtime-exhausted outcome instead of matching retained stderr, so a report beyond the retention budget, or one whose process then overflowed its output budget, is still reported as memory exhaustion. * refactor(evm): classify EVMole worker outcomes through the shared provider classifier (#10716) * refactor(evm): classify EVMole worker outcomes through the shared provider classifier The EVMole worker's cancellation, deadline, output budget and CPU/file-size signals now go through classifyProviderOutcome; only the prlimit launch refusal and the reserved EFBIG exit remain in its dialect. The worker is opted into V8 exhaustion scanning so a heap report names its fixed 256 MiB heap. providerOutcomeOf now reads a launch refusal only from a spawn errno, so a private-storage or carrier read errno is no longer reported as a limiter launch failure. * fix(evm): keep a stream failure's exit status and update Linux worker expectations * refactor(process): read launch refusals through the launcher identity owner * refactor(wasm): classify WABT command outcomes through the shared provider classifier (#10727) * refactor(wasm): classify WABT command outcomes through the shared provider classifier WABT's cancellation, command deadline, output budget, and inherited-limit signals now go through classifyProviderOutcome; its dialect keeps only the configuration-probe and launch-refusal unavailability and the unclassified-exit output error. A tool ended by SIGXCPU/SIGXFSZ or the memory limit is now a resource constraint instead of an output error, and a refused launch in the producer phase is reported as unavailable. The shared timeout context gains the analysis setting that selected the deadline, and the output-limit context may name its exceeded budget. * fix(wasm): keep setup guidance when a WABT version probe's output cannot be collected * refactor(providers): classify raw provider failures through one owner * refactor(process): build classified cancellations with cancelledBy and the carried caller reason * chore(lint): count runOwned's close-failure mapper from main in the classifier baseline * fix(process): carry the runtime's exhaustion report on every memory error that claims it SQLite and historical-capture memory errors recognised a streamed V8 heap report but dropped it, so a report outside retained output reached callers without its source line or omission flags. One projection, runtimeExhaustionReport, now owns that shape for the shared classifier and both consumers. Also lowers the EVMole and WABT cancellation-constructor baselines. * fix(process): keep the provider's recovery for a native-thread exhaustion report The shared classifier replaced the provider-supplied recovery with generic capacity advice whenever the JVM reported it could not create a native thread, dropping Apktool's launcher guidance and flipping retryable to true. The provider's recovery now wins; the capacity advice remains the fallback for providers that supply none. * refactor(pwntools): classify pwntools failures through the shared provider classifier (#10782) * refactor(pwntools): classify pwntools failures through the shared provider classifier pwntools' per-site classifier is replaced by pwntoolsFailureDialect for classifyProviderFailure. Command outcomes go through classifyProviderOutcome, launch refusals through launcherRefusalOf instead of a 'spawn ' syscall prefix check, the input limit through the file dialect's fileSize, and the cleanup report through commandCleanup. The shared read cancellation now carries the reader's partial observation, and resource-signal reports accept provider detail. * fix(pwntools): report a failed command's output once and expect resource_constraint for overflow The shared outcome owner already attaches the command's output as capturedOutput, so the pwntools adapter fallback no longer copies the same text into diagnostics.stdout, diagnostics.stderr and diagnostics.captured_output; diagnostics keep the exit facts. Update the overflow expectations the dialect migration missed (layout provider cleanup and over-budget rows, pwntools cleanup) to resource_constraint. * refactor(wasm): leave WABT cancellation to the shared owners WabtFailures matched any Error named AbortError as a cancellation. No WABT path produces one: reads, path checks and owned commands report cancellation as ArtifactReaderFailure or OwnedCommandFailure, which classifyProviderFailure and classifyProviderOutcome already classify with the caller's reason. The provider's two signal checks now build the cancellation with cancelledBy. Lowers the AnalysisCancelledError constructor baseline for both WABT files to zero. * fix(wasm): report a cancelled snapshot write as the caller's cancellation The private snapshot write passed the caller's signal to Node's writeFile, whose abort envelope reached the dialect's unclassified output failure once the name-based AbortError guess was removed. The write now turns the envelope carrying its own signal's reason into cancelledBy at the producer. * refactor(firmware): classify firmware failures through the shared provider classifier (#10810) Firmware producers now report their own deadline expiry: the start check, the output inventory and launcher admission throw the phase timeout where they observe the abort, and a read the phase signal cancelled reports it through the dialect's interruption. The classifier no longer rereads a cancellation's reason as a timeout. A new readCleanup hook keeps firmware's cleanup report shape. * refactor(captures): classify TShark, sigrok and pcap failures through the shared provider classifier TsharkCaptureProvider and SigrokRecordingProvider replace #failure with a dialect, and PcapProvider replaces analysisFailure and the tool-identity classifier. ArtifactAnalysisResources exposes its command context and a readCleanupFailure composer so the readCleanup hook keeps each provider's cleanup report shape. * refactor(jeb): classify JEB failures through the shared provider classifier JEB's raw MCP failures go through classifyProviderFailure with a JEB dialect; a typed attribution step reports a shared phase's failure under the REA operation. Each MCP phase deadline now reports its own interruption when it aborts, deciding a cancellation's owner from the caller's own signal instead of comparing abort reasons. A refusal carrying the JVM's OutOfMemoryError report becomes a resource constraint naming JEB's Java heap. * fix(jeb): advise the JVM limit that governs the reported memory area * refactor(ghidra): classify Ghidra failures through the shared provider classifier PSP extension inspection reports through classifyProviderFailure with a Ghidra dialect. The startup deadline decides at abort time whether the shared startup owner closed it, so Ghidra and Hopper no longer compare the abort reason with the owner's sentinel, and Ghidra's startup no longer compares a producer cancellation's reason with the deadline's. Three helpers that only construct one error kind now name that kind instead of AnalysisError. * refactor(hopper): classify original-source read failures through the shared provider classifier (#10838) * test(ghidra): pin the aborted startup deadline over a producer cancellation * refactor(kuna): classify Kuna failures through the shared provider classifier Session operations, the workspace copy and the project export report raw failures through classifyProviderFailure with Kuna dialects; the copy and export keep their cleanup report shapes through the readCleanup hook. * refactor(adb): report a pulled file's digest failure from its own type * refactor(ghidra): classify Ghidra failures through the shared provider classifier (#10836) * refactor(ghidra): classify Ghidra failures through the shared provider classifier PSP extension inspection reports through classifyProviderFailure with a Ghidra dialect. The startup deadline decides at abort time whether the shared startup owner closed it, so Ghidra and Hopper no longer compare the abort reason with the owner's sentinel, and Ghidra's startup no longer compares a producer cancellation's reason with the deadline's. Three helpers that only construct one error kind now name that kind instead of AnalysisError. * refactor(hopper): classify original-source read failures through the shared provider classifier (#10838) * test(ghidra): pin the aborted startup deadline over a producer cancellation * refactor(kuna): classify Kuna failures through the shared provider classifier (#10843) Session operations, the workspace copy and the project export report raw failures through classifyProviderFailure with Kuna dialects; the copy and export keep their cleanup report shapes through the readCleanup hook. * chore(guards): shrink the cancellation construction baseline after merging the base |
||
|
|
5d1a47768a |
feat(artifacts): surface the named integrity check in public artifact errors (#11052)
* feat(artifacts): surface the named integrity check in public artifact errors ArtifactOperationError now carries integrityCheck from the reader failure and projects it as details.integrity_check, including with artifact integrity details. Rebuild sites copied a different subset of reader facts each (ProcessCli.artifactFailureFacts, withCleanup, desktop, file-operation cleanup, resource export, DMG inventory, safe output tree); they now spread ArtifactReaderFailure.primaryFacts(), so a new reader fact has one owner. ArtifactIntegrityCheck moves to the domain beside ArtifactAdmissionLimit. * test(artifacts): check rebuilt cleanup failures keep the named integrity check |
||
|
|
47d14d0fb8 |
refactor(verify): give the javascript verifiers' roots to VerifierFixture (#11068)
* refactor(verify): give the javascript verifiers' roots to VerifierFixture VerifierFixture.retain(reason) keeps a root that an owned command whose cleanup is incomplete may still use, replacing each verifier's local retain flag and cleanup closure. * refactor(verify): give the Ghidra COM, DOS, 6502, NativeAOT and raw verifiers' workspaces to VerifierFixture (#11070) * refactor(verify): give the Ghidra COM, DOS, 6502, NativeAOT and raw verifiers' workspaces to VerifierFixture * refactor(verify): keep the Ghidra decompiler-failure, decompile-timeout and no-return workspaces through VerifierFixture until owned cleanup is verified (#11077) |
||
|
|
ecab89f3e6 |
fix(native): report a signature inspection defect as an adapter failure (#11069)
withSignatureTarget wrapped every throw from the inspection callback as
AnalysisOutputError("Native output parsing failed"), so an
InternalInvariantError (a REA defect) was reported as malformed native
command output. A defect now leaves the owned work, so runOwned releases
the private signature copy first and reports the defect as the native
provider's adapter failure. If releasing the copy also fails, the defect
stays primary and the cleanup failure joins it through the shared cleanup
composition (analysisErrorWithCleanupFailure + bindCleanupDependencies).
|
||
|
|
1b8dc202d1 |
refactor(verify): count plain throws in parser-folder process-lifecycle owners (#11071)
JadxWorkspaceRoot and PwntoolsDecoder are exempt from parser-plain-throw because their plain throws report a private helper's process failures. The exemption left later throws in those files unchecked. A counted lifecycle-plain-throw guard now records their current throws (4 and 1); the baseline may only shrink, so a parse fault or defect added there must use ParseFailureError or invariantViolation. |
||
|
|
bae5d74eb0 | refactor(ida): require the host platform for IDA MCP connections and snapshot the child environment with it (#11073) | ||
|
|
9be6a96fd6 |
refactor(cli): project reconstruction and source-to-bundle documents from their contracts (#10697)
* refactor(cli): project reconstruction ledger and coverage commands from their contracts * refactor(cli): project compare-source-to-bundle from its contract and refuse omitted document fields * fix(cli): advertise caller paths in JSON documents as the CLI admits them * fix(cli): advertise that JSON document caller paths exclude URLs * refactor(cli): narrow omitted document field refusal to object documents * test(cli): give the coverage document fixture the current evidence_format |
||
|
|
fd2eabb12a |
feat(setup): manage fx, Junie, Goose and Kilo registrations through the client table (#10709)
* feat(setup): manage fx registrations with its private profile modes fx becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers fx when ~/.fx or FX_HOME exists. Setup now publishes a private profile through the same owner as mcp add (folder 0700, file 0600) and repairs those modes when the row is otherwise current. Doctor parses fx's array launcher instead of reporting it invalid. * fix(setup): judge fx's private profile by its targets and keep its cleanup owner Address review: privateProfileModesCurrent reads the modes of the canonical file and folder, so a linked profile becomes current; clientConfigurationAligned applies the same modes rule as plan and apply; a private-folder close failure reaches the caller with its cleanup owner instead of becoming a write failure; and the setup plan names the folder and file modes it sets. * fix(setup): keep fx's recovery backups owner-only beside a linked profile Setup and uninstall copied a private profile's original bytes with copyFile, so a backup beside a linked ~/.fx/mcp.json kept the target's readable mode outside the folder setup secures. Both now use the owner-only backup owner that mcp add already used. * feat(setup): manage Junie registrations and apply its location policy (#10712) * feat(setup): manage Junie registrations and apply its location policy Junie becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers Junie when its home exists. Whether Junie loads its default user MCP file now has one owner, read through the client policy block that setup, doctor and mcp add already consult: setup and mcp add refuse, and doctor reports, a registration Junie would not load. * fix(setup): read Junie's user configuration as strict JSON Address review: Junie loads config.json as strict JSON, so comments, trailing commas or an empty file leave its MCP location choice unknown, as before the move into the row. Filesystem tests also clear JUNIE_*, FX_HOME and MCPORTER_CONFIG so a developer's own client locations cannot be inspected or removed. * test(setup): keep the detected client order out of the lifecycle suite body The expected detection order grew with each folded client until the suite callback exceeded the max-lines-per-function lint limit. * fix(update): report a client whose policy setup refuses instead of failing maintenance Junie's disabled default locations (and Gemini's settings policy) make doctor report the registration stale, but setup refuses that client, so selecting it failed every other client's maintenance. The registration inspection now carries the setup blocker, and maintenance lists that client with its reason instead of selecting it. * refactor(setup): read fx's private-profile host through HOST_PLATFORM The fx private-profile mode checks and permissions describe the host REA runs on, so they take it from the host-platform owner instead of reading process.platform (refused by the ratchet from #10911). * feat(setup): manage Goose registrations across its configuration layers (#10715) * feat(setup): manage Goose registrations across its configuration layers Goose becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers Goose when its user file or system file exists. Goose loads its system file and GOOSE_ADDITIONAL_CONFIG_FILES beneath the user file and overlays each extension one field deep; doctor now reports that effective registration, while setup, update and uninstall change only the user file. Doctor also parses Goose's cmd launcher instead of reporting it invalid. * fix(setup): keep Goose's layered environment and load order through setup and uninstall Address review: read Goose's env alias and apply requested settings over envs; keep an inherited lower envs map instead of masking it with an empty default; keep each layer's last load so a repeated user file keeps its precedence; split GOOSE_ADDITIONAL_CONFIG_FILES with Windows quoting; validate only the effective environment across read-only layers; refuse uninstall while a read-only layer keeps REA enabled; and clear Goose's location variables in tests. * fix(setup): apply requested Goose settings over the inherited environment * fix(setup): leave lower-layer Goose settings in force and read admin layers read-only Setup no longer writes its default timeout, enabled, name or description into Goose's user entry when only a lower layer declares that setting, so the inherited value keeps applying and a repeat setup stays current. Uninstall reads Goose's read-only lower layers where Goose reads them, without the write target's ownership check, so an administrator-owned system file no longer blocks removal. The client table accepts an injected Goose system-config path so tests no longer read or skip on the host's /etc/goose/config.yaml; adds a shadowed-invalid-lower-layer regression. * fix(setup): keep an inherited Goose env alias's spelling when writing the user entry Goose overlays each extension field separately, so writing envs into the user file beside a lower layer's env alias left both in force, which readers reject as ambiguous. Setup now writes the user map under the alias a lower layer declares, and mcp add neither adds a default envs map beside an inherited alias nor renames a user alias the lower layer shares. * test(setup): inject Goose's system layer into mcp add selection resolveMcpRegistrationClients accepts the caller's system configuration paths, so the Goose layers test no longer reads the host's /etc/goose/config.yaml. * fix(setup): report REA's Goose registration that only a read-only layer defines * test(setup): pass an isolated Goose system path through update maintenance and the mcp add table * fix(setup): judge Goose uninstall by the merged entry and stop on an unreadable lower layer * fix(setup): select Goose's env alias by presence so a null alias stays malformed * fix(setup): use the shared record predicate for Goose's layered merge after #10588 * feat(setup): give Kilo a client-table row with an async layered location (#10823) * feat(setup): give Kilo a client-table row with an async layered location The client table gains a layeredLocation hook and resolveSupportedClients, which awaits it. Kilo's row resolves its user-scope layers through the same owner rea mcp add uses (KiloClientLocation), so both pick the same write target; the synchronous row keeps kilo.json in Kilo's config root with every candidate layer. The table refuses a relative KILO_CONFIG, KILO_CONFIG_DIR or XDG_CONFIG_HOME because Kilo's working directory is unknown. Refs #7181 * fix(setup): treat every folder Kilo reads as evidence that it is installed * fix(setup): normalize Kilo's absolute table paths and parse its command array * feat(setup): resolve the client table's layered locations in setup, doctor, update and uninstall (#10832) SetupHost (detection and the selectable table), ClientRegistrationStatus, uninstall, doctor's selected-registration environment and the mcp add catalog now read resolveSupportedClients, so each sees the Kilo layer Kilo writes rather than the synchronous default. Refs #7181 * docs(adr): record the one-client-table decision for setup and mcp add * fix(setup): refuse to read a client row whose location is unresolved Doctor's selected-client settings read a Kilo row whose relative KILO_CONFIG left only path evidence, so it inspected a file relative to REA's folder. The shared configuration reader now refuses such a row, so every reader reports the registration as unreadable. * docs(adr): name the row's layeredLocation hook * feat(setup): read KILO_CONFIG_CONTENT as Kilo's top read-only layer (#10851) * feat(setup): read KILO_CONFIG_CONTENT as Kilo's top read-only layer * fix(setup): refuse a Kilo uninstall that would expose or keep another layer's rea entry (#10852) * fix(setup): recheck KILO_CONFIG_CONTENT at write time and name it in doctor's recovery * refactor(mcp): register Kilo through its table row and remove the registration-only catalog kind (#10862) * refactor(mcp): register Kilo through its table row and remove the registration-only catalog kind * refactor(mcp): resolve user-scope targets in the catalog so location modules never import the client table * test(setup): cover Kilo's KILO_CONFIG, home-folder and inline-only layers * fix(setup): report REA's Kilo entry that only KILO_CONFIG_CONTENT sets during uninstall Doctor reports a registration that KILO_CONFIG_CONTENT alone defines, but uninstall found no file entry and reported Kilo as skipped. Uninstall now reports it once as failed and names the variable to edit. * docs(adr): record Kilo's inline layer in the client-table decision * fix(setup): compare Windows environment names without case when a higher layer overrides REA's entry Kilo's inline-layer check and Gemini's system-override check compared environment maps by exact key, so an equal Path beside PATH on Windows was reported as an override and setup refused the client. Both compare the entry as the client launches it. * fix(update): leave a stale Kilo registration KILO_CONFIG_CONTENT sets out of maintenance Setup refuses a refresh the inline layer would override, and one refused client failed every other client's maintenance. The registration inspection now names the inline layer as the setup blocker of a stale entry, and maintenance reports Kilo with that recovery instead of selecting it. * fix(setup): refuse relative JUNIE_HOME and Cline CLI overrides like the other client roots (#10909) * fix(setup): refuse relative JUNIE_HOME and Cline CLI overrides like the other client roots * fix(setup): refuse Windows client paths without a drive that follow the client's current drive * fix(update): select maintenance clients through setup's own refresh refusal check Maintenance predicted setup's refusal with its own rule: any inline rea entry blocked a stale registration, while an aligned one was never checked. A harmless KILO_CONFIG_CONTENT entry (enabled: true) kept a stale Kilo launcher pinned, and an inline value setup would not write (an extra environment variable) let an aligned Kilo registration block every client's maintenance. Setup's refusal checks (client policy, then the inline override comparison of the entry it would write) now live in one reader that setup's alignment check and maintenance share. Maintenance asks it for every owned enabled candidate and reports a refused client with setup's remediation and its real state. * fix(update): keep failed refresh-check reads owned by the supplied maintenance scope clientRefreshRefusal read the client's layers, target file and policy without the caller's resource scope, so a close that failed during those reads threw a cleanup failure no scope retained; maintenance then reported it as text and the scope's close could not retry the descriptor. The refresh reader now takes the scope and passes it to every read. * fix(setup): take the Kilo layer readers' default host from HOST_PLATFORM and the shared record predicate After rebasing on main (#10911, #10588): the new inlineRegistrationOverride and resolveSupportedClients defaults read the running host through the host-platform owner, and the layered launcher merge uses isRecord. * fix(update): keep an unreadable layer's reason in the refresh refusal check readClientRefresh returned undefined for an unreadable or malformed layer, so clientRefreshRefusal reported no refusal and maintenance selected a client whose setup preflight then failed. The reader returns the typed file failure, and the refusal check reports its detail like setup's preflight does. * fix(setup): count REA's entry in KILO_CONFIG_CONTENT as Kilo lifecycle evidence Doctor, update and uninstall inspected a client only when one of its folders existed, so a registration set only by KILO_CONFIG_CONTENT was skipped. A read-only inline layer that sets REA's entry is now evidence on its own. * fix(update): report a client whose only conflict is a discovered provider path as needing setup * fix(update): match discovered settings by the platform's environment identity * fix(update): preflight maintenance with setup's write-target checks and treat discovered inline paths as unknown |
||
|
|
025d1b365f |
refactor(browser): parse frame lifecycle events once by a registered event schema (#10730)
* refactor(browser): parse frame lifecycle events once by a registered event schema CdpConnection admits each event through protocol/CdpEvents.ts, which parses the five Page frame lifecycle events once into identity facts plus a frame URL observation, like a frame-tree node. Screenshot, page capture, the observation timeline, WebMCP, Electron inspection and the execution window read those facts instead of re-parsing the raw payload; CdpFrameFacts no longer carries the raw source record. Playwright CDP session subscriptions name an event from Playwright's protocol table, and an architecture guard counts the remaining raw event payload reads so they can only shrink. * refactor(browser): admit transport events through the registered-event owner Remove the unused cdpFrameUrl wrapper; its fragment cases now exercise observeCdpFrameUrl. Add a connection-level test that two subscribers share one parsed payload and the raw params. |
||
|
|
998faa4118 |
refactor(ida): launch stdio registrations through the owned MCP transport (#10739)
* refactor(ida): launch stdio registrations through the owned MCP transport IDA stdio servers now run as an owned process group (POSIX) or job (Windows) through OwnedMcpStdioTransport instead of the SDK's unowned child. Windows bare commands resolve against the registration PATH/PATHEXT and .cmd/.bat launchers run through the shared WindowsBatchCommand cmd.exe invocation. The frame limit is classified from the transport's typed OwnedMcpOutputLimitError instead of parsing SDK error text, detach no longer reaches into the SDK's private _process, and the per-operation byte budget is optional. * fix(ida): keep owned stdio cleanup observable and resolve Windows interpreter paths - StructuredContentMcpClient observes SDK-initiated closes like OwnedMcpClient, so a failed handshake with incomplete owned cleanup cannot reject unhandled. - OwnedMcpStdioTransport attaches an owner-redacted captured output to cleanup failures; IDA passes its retained stderr tail. - findWindowsExecutable resolves path-qualified commands at their own location with PATHEXT; IDA routes every Windows registration through it and refuses non-drive paths with an actionable remedy before the owned launcher. * fix(process): end a stalled stdio launch when the owned MCP transport closes OwnedMcpStdioTransport passes the launcher a signal it aborts with OwnerCancellation.ownerClosed when it stops, so IDA's Windows PATH/PATHEXT lookup stalled on an unreachable directory no longer holds close() open; IDA reports the interrupted lookup by its abort reason. The IDA environment tests use createTestTempDirectory for owned temporary roots. * fix(ida): bound the Windows command lookup by the registration timeout The PATH/PATHEXT search for a stdio registration now runs under a ProviderStartupDeadline of the registration's timeoutMs that also follows the transport's close signal. A lookup stalled on an unreachable PATH directory ends as an AnalysisTimeoutError (phase windows_path_lookup) instead of leaving connect() pending, matching Apktool's Windows lookup. * test(ida): stub REA's PATH again now that process inspection runs ps from fixed locations * test(ida): pass the required registration protocol in owned-stdio fixtures * fix(ida): report an uninspectable Windows command candidate with its path and code * refactor(ida): take the host platform from composition, not an ambient read * fix(verify): pass the host platform to the real IDA upstream check * fix(process): keep a failed launch's preparation cleanup owned by the stdio transport's close OwnedMcpStdioTransport discarded the launch rejection before a supervisor existed, so an ownership-helper preparation that transferred a cleanup owner (or reported a cleanup failure without one) was dropped and close() reported success. The transport's close now closes each transferred owner from processInspectionCleanupFailures, and reports a ProviderCleanupError naming the preparation resource until it does; a later close retries it. |
||
|
|
607a7872bb |
refactor(jeb): classify JEB failures through the shared provider classifier (#10831)
* fix(pcap): report a refused tool launch as an unavailable tool When a capture read's tool launch was refused with EPERM, pcap reported it as unreadable tool output (AnalysisProtocolError) instead of an unavailable tool. Pcap also never told "not executable" apart from "missing". Add classifyLaunchFailure in src/process as the one owner of which spawn errnos mean missing (ENOENT, ENOTDIR) and which mean present but not executable (EACCES, EPERM, ENOEXEC, EISDIR). Pcap, apktool and gdb used three different errno lists; all three now use it. * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * refactor(process): classify Java and adb launch refusals with the shared owner (#10598) The Ghidra and JADX Java probes and adb's version probe now take missing-versus-not-executable from classifyLaunchFailure instead of their own errno checks. ELOOP and ENAMETOOLONG join the owner's missing set, so adb keeps its existing classification and both Java probes now treat a non-directory path component as a missing runtime. * fix(pcap): preserve command launch attribution * test(pcap): expect an unknown failing stage when a limited capture tool exits unsuccessfully * refactor(process): classify owned command outcomes through one owner Add ProviderOutcome, read once from the supervisor's facts, and classifyProviderOutcome, the one mapping from an outcome to a typed error. Migrate pcap and the shared artifact producer command failure (TShark, sigrok). Add the rea/provider-failure-classifier lint rule with a shrink-only baseline of per-site (cause: unknown) => AnalysisError functions. * test(lint): cover baselined files in the provider-failure classifier rule * fix(apktool): report the decoder JVM's heap exhaustion as memory, not a target refusal The supervisor now watches for a managed runtime's out-of-memory report while output streams (JVM java.lang.OutOfMemoryError, V8 'JavaScript heap out of memory'), so a retention budget cannot hide it. ProviderOutcome gains a runtime-exhausted kind and classifyProviderOutcome maps it once. Apktool decode opts in and moves to the shared classifier; Ghidra's single-purpose output token becomes the JVM runtime option and its area matching reuses the shared table. * fix(process): keep the runtime's out-of-memory report on the memory error it supports * fix(pcap): attribute a limited capture's exit through the prlimit wrapper * fix(process): keep a shortened out-of-memory line marked as shortened * fix(process): identify the refused executable for every launcher shape Name the executable on errnos Node throws synchronously from spawn (ENOEXEC, ENOTDIR, ...) and read the Windows native launcher's executable-launch constraint, so pcap attributes those refusals to the selected tool or limiter instead of an unknown stage. * test(pcap): prove synchronous launch naming with ENOTDIR on every POSIX host * fix(apktool): advise the JVM limit that governs the reported memory area * fix(ghidra): read the supervisor's parsed OOM area instead of reparsing lines * fix(sqlite,capture): read V8 heap exhaustion from streamed output, not retained stderr (#10724) The SQLite worker and the Node capture decoders now declare runtime: "v8", so the supervisor observes V8's heap report as output streams. Both classifiers read the runtime-exhausted outcome instead of matching retained stderr, so a report beyond the retention budget, or one whose process then overflowed its output budget, is still reported as memory exhaustion. * refactor(evm): classify EVMole worker outcomes through the shared provider classifier (#10716) * refactor(evm): classify EVMole worker outcomes through the shared provider classifier The EVMole worker's cancellation, deadline, output budget and CPU/file-size signals now go through classifyProviderOutcome; only the prlimit launch refusal and the reserved EFBIG exit remain in its dialect. The worker is opted into V8 exhaustion scanning so a heap report names its fixed 256 MiB heap. providerOutcomeOf now reads a launch refusal only from a spawn errno, so a private-storage or carrier read errno is no longer reported as a limiter launch failure. * fix(evm): keep a stream failure's exit status and update Linux worker expectations * refactor(process): read launch refusals through the launcher identity owner * refactor(wasm): classify WABT command outcomes through the shared provider classifier (#10727) * refactor(wasm): classify WABT command outcomes through the shared provider classifier WABT's cancellation, command deadline, output budget, and inherited-limit signals now go through classifyProviderOutcome; its dialect keeps only the configuration-probe and launch-refusal unavailability and the unclassified-exit output error. A tool ended by SIGXCPU/SIGXFSZ or the memory limit is now a resource constraint instead of an output error, and a refused launch in the producer phase is reported as unavailable. The shared timeout context gains the analysis setting that selected the deadline, and the output-limit context may name its exceeded budget. * fix(wasm): keep setup guidance when a WABT version probe's output cannot be collected * refactor(providers): classify raw provider failures through one owner * refactor(process): build classified cancellations with cancelledBy and the carried caller reason * chore(lint): count runOwned's close-failure mapper from main in the classifier baseline * fix(process): carry the runtime's exhaustion report on every memory error that claims it SQLite and historical-capture memory errors recognised a streamed V8 heap report but dropped it, so a report outside retained output reached callers without its source line or omission flags. One projection, runtimeExhaustionReport, now owns that shape for the shared classifier and both consumers. Also lowers the EVMole and WABT cancellation-constructor baselines. * fix(process): keep the provider's recovery for a native-thread exhaustion report The shared classifier replaced the provider-supplied recovery with generic capacity advice whenever the JVM reported it could not create a native thread, dropping Apktool's launcher guidance and flipping retryable to true. The provider's recovery now wins; the capacity advice remains the fallback for providers that supply none. * refactor(pwntools): classify pwntools failures through the shared provider classifier (#10782) * refactor(pwntools): classify pwntools failures through the shared provider classifier pwntools' per-site classifier is replaced by pwntoolsFailureDialect for classifyProviderFailure. Command outcomes go through classifyProviderOutcome, launch refusals through launcherRefusalOf instead of a 'spawn ' syscall prefix check, the input limit through the file dialect's fileSize, and the cleanup report through commandCleanup. The shared read cancellation now carries the reader's partial observation, and resource-signal reports accept provider detail. * fix(pwntools): report a failed command's output once and expect resource_constraint for overflow The shared outcome owner already attaches the command's output as capturedOutput, so the pwntools adapter fallback no longer copies the same text into diagnostics.stdout, diagnostics.stderr and diagnostics.captured_output; diagnostics keep the exit facts. Update the overflow expectations the dialect migration missed (layout provider cleanup and over-budget rows, pwntools cleanup) to resource_constraint. * refactor(wasm): leave WABT cancellation to the shared owners WabtFailures matched any Error named AbortError as a cancellation. No WABT path produces one: reads, path checks and owned commands report cancellation as ArtifactReaderFailure or OwnedCommandFailure, which classifyProviderFailure and classifyProviderOutcome already classify with the caller's reason. The provider's two signal checks now build the cancellation with cancelledBy. Lowers the AnalysisCancelledError constructor baseline for both WABT files to zero. * fix(wasm): report a cancelled snapshot write as the caller's cancellation The private snapshot write passed the caller's signal to Node's writeFile, whose abort envelope reached the dialect's unclassified output failure once the name-based AbortError guess was removed. The write now turns the envelope carrying its own signal's reason into cancelledBy at the producer. * refactor(firmware): classify firmware failures through the shared provider classifier (#10810) Firmware producers now report their own deadline expiry: the start check, the output inventory and launcher admission throw the phase timeout where they observe the abort, and a read the phase signal cancelled reports it through the dialect's interruption. The classifier no longer rereads a cancellation's reason as a timeout. A new readCleanup hook keeps firmware's cleanup report shape. * refactor(captures): classify TShark, sigrok and pcap failures through the shared provider classifier TsharkCaptureProvider and SigrokRecordingProvider replace #failure with a dialect, and PcapProvider replaces analysisFailure and the tool-identity classifier. ArtifactAnalysisResources exposes its command context and a readCleanupFailure composer so the readCleanup hook keeps each provider's cleanup report shape. * refactor(jeb): classify JEB failures through the shared provider classifier JEB's raw MCP failures go through classifyProviderFailure with a JEB dialect; a typed attribution step reports a shared phase's failure under the REA operation. Each MCP phase deadline now reports its own interruption when it aborts, deciding a cancellation's owner from the caller's own signal instead of comparing abort reasons. A refusal carrying the JVM's OutOfMemoryError report becomes a resource constraint naming JEB's Java heap. * fix(jeb): advise the JVM limit that governs the reported memory area * refactor(ghidra): classify Ghidra failures through the shared provider classifier (#10836) * refactor(ghidra): classify Ghidra failures through the shared provider classifier PSP extension inspection reports through classifyProviderFailure with a Ghidra dialect. The startup deadline decides at abort time whether the shared startup owner closed it, so Ghidra and Hopper no longer compare the abort reason with the owner's sentinel, and Ghidra's startup no longer compares a producer cancellation's reason with the deadline's. Three helpers that only construct one error kind now name that kind instead of AnalysisError. * refactor(hopper): classify original-source read failures through the shared provider classifier (#10838) * test(ghidra): pin the aborted startup deadline over a producer cancellation * refactor(kuna): classify Kuna failures through the shared provider classifier (#10843) Session operations, the workspace copy and the project export report raw failures through classifyProviderFailure with Kuna dialects; the copy and export keep their cleanup report shapes through the readCleanup hook. * chore(guards): shrink the cancellation construction baseline after merging the base |
||
|
|
15de1d4dce |
feat(evidence)!: require JavaScript, browser, managed and reference-source facts their producers always write (#10990)
* feat(javascript)!: require the runtime parse-failure count and active Electron execution paths The V8 Inspector projection always writes scripts.parse_failed_total and the active Electron service always commits parameters.resolved_paths, so both are now required. Runtime reconciliation reads the admitted execution paths only and no longer falls back to request-spelled paths in parameters, and checks the observed executable path against them on every capture. JavaScriptStaticAnalysis.routes and module_runtime keep their omission, which current producers still make (a checkpoint that cannot retain route facts; no recovered factory runtime); their comments now say so instead of naming historical analyses. BREAKING CHANGE: JavaScript runtime observations without scripts.parse_failed_total, and active Electron Evidence without parameters.resolved_paths, are refused as malformed; recreate the observation. * test(javascript): give the shared Node reconciliation fixture the required parse-failure count * feat(browser)!: require browser observation facts their producers always write (#10991) * feat(browser)!: require browser observation facts their producers always write The source-map fetcher always writes effective_url (string or null), the web bundle analyzer always writes schema_property_names_coverage, and the CDP storage fingerprinter always marks IndexedDB schema fingerprints with projection_version 2. Each is now required. The IndexedDB marker is tied to its scope by a discriminated union and derived from the scope in the producer, so compare_web_captures no longer carries the store-only projection branch. response_identity and the WebMCP consequential hint keep their omission, which current producers still make (a body not fully read; an invalid annotation); the guide no longer attributes it to historical captures. BREAKING CHANGE: source-map items without effective_url, WebMCP declarations without schema_property_names_coverage, and IndexedDB schema fingerprints without projection_version are refused as malformed; recreate the capture. * feat(managed)!: refuse members beside a null signature resolution (#10992) * feat(managed)!: refuse members beside a null signature resolution signature_resolution is null only when member decoding exceeded capacity, and the capacity-recovery producer then examines no members. The managed member inspection schema now enforces that: a null resolution with any field, method, member reference, call edge or field access is malformed. With that rule, every admitted inspection with members attests type-name resolution, so the raw-digest fallback is unreachable and is deleted: comparableSides, hasSignatureResolution, the comparison's signatureResolutionExamined flag and the "does not attest" limitation. The shared workflow example that carried resolved digests beside a null attestation now attests resolution. BREAKING CHANGE: managed member Evidence with a null signature_resolution and any examined member is refused as malformed; recreate the observation. * docs: describe historical Evidence by what the format revision now refuses (#10993) SQLite worker_timeout_ms is required, so the SQLite guide no longer reads a missing value as unknown settings. The IL2CPP, ESP image and process capture guides now say that bundles exported without evidence_format are refused, while a standalone record from an earlier release is still read with the stated omission semantics (records carry no format marker yet). The route inventory guide describes a parent without route_inventory by its meaning rather than by its age. * refactor(javascript): require static analysis coverage from the JavaScript worker (#11001) * refactor(javascript): require static analysis coverage from the JavaScript worker Both JavaScript static producers always write analysis_coverage: the analyzer measures it on every parsed source and the failed-parse result carries an unexamined coverage. The worker schema and the static analysis type therefore require it, the preload-discovery checkpoint copies it unconditionally, and ElectronBoundaryAnalysis reads Electron applicability and examination limits from it alone. The fallback that re-derived Electron use from semantic module links and retained references for analyses without coverage is deleted, as are the graph and builder branches for a missing coverage. Retained Evidence graph observations are unchanged: the analysis view still counts a stored JavaScript observation without analysis_coverage as unmeasured, since standalone records carry no format marker yet. The worker runs from the same build as its parent, so no external caller sees the stricter reply schema. * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts (#11002) * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts Each field is written by its only producer on every capture: - The CDP storage capture always writes content_fingerprints, fingerprint_algorithm and fingerprints_complete, so their schema defaults are removed. - The CDP Link header projection always writes context_url and context_scope, so they are required. - The source-map fetcher writes source_index and declaration_index on every mapping row, so they are required. - The fetcher judges a map invalid only after reading its complete body. A separate invalidSourceMapItem builder now takes the response identity as a required argument, and the schema's invalid member requires response_identity; fetch_failed keeps it optional because those rows can come from a body that was not fully read. The browser and source-location guides no longer describe these fields as optional for older saved captures. BREAKING CHANGE: page inspections without the storage fingerprint fields or Link context fields, source-map mapping rows without their indexes, and invalid source-map items without response_identity are refused as malformed; recreate the capture. * test(browser): keep source-omission coverage on a still-defaulted field and refuse a missing fingerprint algorithm * feat(browser)!: require web-bundle target origin, inspection producer facts, scenario redirect state and exclusion kind (#11014) feat(browser)!: require web-bundle target origin, page inspection producer facts, scenario redirect state and exclusion kind Each field is written by its only producer on every record: - buildCaptureObservation always writes capture.target_origin (the validated origin or null), so analyze_web_bundle Evidence and both web-bundle view results require it; the view's conditional spread is gone. - The CDP page capture always writes accessibility node states, script frame_id (null when unattributed) and worker opener_target_id and parent_frame_id, so their schema defaults are removed. - PlaywrightScenarioNetwork writes redirected_from_transaction_state exactly when the predecessor ID is null, so request events now require it there and still refuse it on linked events. - The reference-source importer writes entry_kind on every exclusion (unknown when the kind was not observed), so it is required. The browser scenario contract and CLI guide no longer describe older captures or exclusions without these fields. BREAKING CHANGE: web-bundle analyses without capture.target_origin, page inspections without these script, accessibility or worker fields, scenario network events with a null predecessor and no redirect state, and reference source graphs whose exclusions lack entry_kind are refused as malformed; recreate the capture or re-import the source. |
||
|
|
a6cbe8b12a |
feat(providers): bound runOwned work and close by one deadline (#10996)
* feat(providers): bound runOwned work and close by one deadline * fix(providers): read an expired budget at settle time and keep a caller abort during cleanup * fix(providers): follow a late close rejection's owner and keep captured output through budget replacements * fix(providers): track budget expiry apart from the caller, keep replaced work's cleanup, treat empty leases as none * fix(providers): classify thrown abort reasons, keep recorded failures and follow a late close owner's resources Work that throws its signal's abort reason (throwIfAborted) is now a cancellation, so an elapsed budget becomes a timeout and a caller abort stays a cancellation. A budget cancellation replaced by a timeout or a caller cancellation keeps the secondary failures it recorded. A late close rejection that names its own owner now also supplies the retained failure's resources. * fix(providers): classify only the budget's own abort reason, and follow only a late rejection that reports its own cleanup A caller's abort reason is opaque, so a thrown value equal to it stays the work's failure with the caller's cancellation retained; only the budget's typed OwnerCancellation.deadlineElapsed marks a thrown abort as the budget's. A late close rejection without unreleased cleanup of its own (such as a cancellation) no longer confirms release or replaces the fallback resource. * fix(providers): follow a late close owner that already released, by cleanup ownership not completion AnalysisError.carriesCleanup owns whether an error ever owned cleanup, apart from whether it finished. runOwned's late close rejection uses it, so a producer error released by a concurrent retry still confirms release, while a cancellation without cleanup keeps the close's lease pending. Uninstall and SetupCleanupOwner used the same four-clause predicate locally; they now read the owner. |
||
|
|
d8c0a71c53 |
feat(artifacts): name which ASAR integrity check failed on the reader failure (#11021)
* feat(artifacts): name which ASAR integrity check failed on the reader failure * test(artifacts): assert the ASAR stream's declared-size and read-coverage checks * fix(artifacts): report a close queued behind ASAR preparation as unavailable The missing-snapshot check was reachable when close() ran between a prepareContainer() and the following entries() or openContainer() operation, and reported a caller close as an integrity failure. Classify it like the sibling closed-inventory check and cover foreign-entry with a stale entry opened after close. |
||
|
|
63b0426e40 |
fix(errors): rethrow internal invariant violations from plist consumers and the native output projection (#11029)
* fix(plist): rethrow internal invariant violations from plist consumers KeyedArchiveReader reported any non-limit decode failure as a format failure, InterfaceBuilderAnalysis listed it as an invalid archive, ReleaseExposureReader fell back to scanning raw bytes, and the native plist parser reported it as provider output. An InternalInvariantError is a REA defect, not evidence about the input, so each consumer now rethrows it. The native parser's binary path now shares its one cause projection instead of a duplicate. * fix(native): rethrow internal invariant violations from the native output projection nativeOutputFailure wrapped any producer failure as AnalysisOutputError, so a REA defect thrown while reading a plist or dispatching a command was reported as native output parsing. It now rethrows InternalInvariantError, which reaches the provider's adapter-failure path with the invariant as its cause. * fix(artifacts): rethrow internal invariant violations from the shared artifact failure mapper translateArtifactFailure turned every unrecognised cause into an ArtifactOperationError with reason io, so the keyed-archive and Interface Builder rethrows still reached users as artifact read failures. The shared mapper now rethrows InternalInvariantError, and the deferred client reports it as a ProviderAdapterError. Provider-level tests drive both operations through that client. * refactor(dotnet): report managed reader defects through invariantViolation (#11030) * refactor(dotnet): report managed reader defects through invariantViolation The managed readers threw plain TypeError and RangeError for states their callers rule out: an allowance or method page outside the input schema, a missing snapshot after identity admission, and a missing CLI header after the caller already returned for it. These are REA defects, not malformed targets, so they throw invariantViolation. The two CLI re-checks are gone: the callers pass the CLI header they already narrowed. The dotnet parser-plain-throw baseline drops from 6 to 0. * refactor(providers): refuse unusable tool paths and record marker mismatches without throwing to their own catch (#11031) * refactor(firmware): refuse unusable tool paths without throwing to its own catch resolveFirmwareCommand threw a plain TypeError for a configured engine or limiter path that is not a regular file, only to catch it in the next line and wrap it as an unavailable capability. A helper now returns why a path cannot run, and each caller builds the one refusal directly. Refusal reasons are unchanged; the directory tests now pin them exactly. The firmware parser-plain-throw baseline drops from 2 to 0. * refactor(pwndbg): refuse unusable debugger paths without throwing to its own catch inspectPwndbgCore threw plain Errors for a relative or wrong-kind configured path only to catch them and wrap them as an unavailable capability. A helper now returns why a path cannot be used, with any host error as its cause, and the loop builds the one refusal. Cancellation between host checks still propagates. Refusal reasons are unchanged. The PwndbgCoreContext parser-plain-throw baseline entry is removed. * refactor(pwntools): record a mismatched failure marker without throwing to its own catch readPwntoolsFailureEvidence threw a plain Error when the private bridge marker disagreed with the exit status, only to catch it and record its message as the marker failure. The mismatch is now recorded directly. The recorded evidence is unchanged; a unit test pins both the matching and the mismatched marker. The PwntoolsResourceLimits parser-plain-throw baseline entry is removed. * fix(android): report an unobserved Java probe as a REA defect, not a Java refusal (#11032) * fix(android): report an unobserved Java probe as a REA defect, not a Java refusal When runOwnedCommand resolved without observing the completed run, the probe threw a plain Error that its catch then classified as a Java runtime refusal, telling the caller to review their launcher. The state is a broken internal assumption, so the probe throws invariantViolation and projects it as a jadx adapter failure. The JadxJavaProbe parser-plain-throw baseline entry is removed. * refactor(native): report native provider defects through invariantViolation (#11033) * refactor(native): report native provider defects through invariantViolation Native providers threw plain Error and TypeError for states their own earlier steps rule out: a client with no target, a measured slice with no selection, a read longer than requested, a decoder command without its runtime, an LLDB root released before its children, and an IPS integer fact from another reader. These are REA defects, so they throw invariantViolation. NativeUiInterruptionControl no longer needs a throw: recording the deadline interruption returns the interruption its error is built from. Six native parser-plain-throw baseline entries drop. * refactor(native): report malformed lipo, swift-demangle and UI helper output through ParseFailure (#11034) * refactor(native): report malformed lipo and swift-demangle output through ParseFailure The lipo and swift-demangle output parsers threw plain TypeError for output that breaks their framing, and the lipo result classifier caught every TypeError as malformed output, so a host TypeError from a REA defect was reported as lipo output. Both parsers now throw malformedInput with their own format, and the lipo classifier accepts ParseFailureError instead of TypeError. Messages and the consumers' output and format failure categories are unchanged. Four native parser-plain-throw baseline entries drop. * refactor(native): report the UI helper's non-JSON output through ParseFailure The native UI helper runtime threw a plain Error when the helper's stdout was not JSON. It now throws malformedInput with its own format and the JSON failure as cause. The observation boundary still reports it as a native-macos adapter failure with the same reason. The NativeUiHelperRuntime parser-plain-throw baseline entry is removed. * refactor(verify): keep process-lifecycle owners out of the parser plain-throw guard (#11035) * refactor(verify): keep process-lifecycle owners out of the parser plain-throw guard JadxWorkspaceRoot and PwntoolsDecoder sit in parser folders but own a private helper process; their remaining plain throws report the helper's startup, handshake and cleanup outcomes, not parse faults. The guard now names them as process-lifecycle owners and leaves them out, so their five baseline entries drop without inventing parse errors for process failures. * refactor(parsers): report the remaining artifact, il2cpp, model and domain defects through invariantViolation (#11036) * refactor(parsers): report the remaining artifact, il2cpp, model and domain defects through invariantViolation Nine plain Error, TypeError and RangeError throws in parser folders reported broken internal assumptions or caller contracts (an uninitialized ZIP or DMG reader, a missing scan result, a non-byte stream chunk, an invalid traversal or marshal limit, a header count or linking fact the reader itself should have produced, a misordered Safetensors budget, an append after fingerprinting). None is an input fault, and no catch site depends on their class. They now throw invariantViolation with the same messages, and their parser-plain-throw baseline entries drop. * refactor(evidence): refuse an earlier Evidence format through ParseFailure (#11037) * refactor(evidence): refuse an earlier Evidence format through ParseFailure UnsupportedEvidenceFormatError restated the ParseFailure algebra as its own TypeError subclass. The format owner now throws unsupportedInput for the evidence-bundle format at the evidence_format field and exports the predicate its consumers use. The bundle reader's unsupported-format kind and message are unchanged. The snapshot reader surfaced only TypeError messages, so it now also surfaces the format refusal and keeps its recreate guidance; a boundary test pins that. * refactor(native): report Mach-O reader and inspection defects through invariantViolation (#11042) The Mach-O inspection plan reads the lipo, nm and dyld_info captures it just ran, the dispatch metadata reader is called only for Mach-O executables, and the command-name reader takes limits its callers derive. A missing capture, a non-Mach-O target or a malformed limit is a REA defect, not an input fault, so these six sites throw invariantViolation with their existing messages instead of TypeError. No catch site depends on their class. Their parser-plain-throw baseline entries drop. * fix(artifacts): join the Interface Builder cleanup failure to a catalog defect When catalog work failed while the concurrent Interface Builder reader failed to close, analyzeAppleAssetCatalogs built the primary through translateArtifactFailure before joining cleanup. That mapper now rethrows an InternalInvariantError, so a defect skipped the join and the reader's retained resources were lost. The defect now becomes the artifact graph provider's adapter failure at that site and joins the cleanup failure as before. |
||
|
|
530faf43bd |
refactor(process): take the host from HOST_PLATFORM and require the platform in process helpers (#11038)
* refactor(process): take the host from HOST_PLATFORM and require the platform in process helpers * refactor(process): require the settlement platform and pass it in string-embedded ownership checks |
||
|
|
0d86953c32 |
feat(evidence): name a standalone Evidence record with detected_kind on every bundle refusal (#11039)
The file reader, inline bundle reader and investigation ledger refused a single Evidence record with only a message saying so. The file reader's wrong-kind failure now carries detected_kind "evidence-record" (as it already did for analysis snapshots), and the inline and ledger refusals carry it on their input issue through one domain helper. Tests assert the field instead of the sentence. The inline CLI/MCP case now asserts full parity: since compact input schemas, MCP reaches the same domain reader. |
||
|
|
bcb068cc04 |
fix(rizin): refuse a start after shutdown began as an owner-closed cancellation (#11041)
OwnedDebuggerSessionRegistry owns the rule: closeStarts refuses later starts as owner-closed (a caller that already aborted keeps its own reason) and aborts in-flight ones. Rizin no longer reports an inferior_tty input error for a start made after closeAll began; GDB's local copy of the rule is gone. User-visible: start_rizin_debug_session called while REA is shutting down now fails as a cancellation (owner closed) instead of an input error naming inferior_tty, matching start_gdb_session. |
||
|
|
423489a761 |
feat(evidence): name the side and issue path of comparison source integrity failures (#11049)
* feat(process): name the side and issue path of process-capture integrity failures compare_process_captures reported which side failed validation, and where, only in the message. EvidenceIntegrityError now carries an optional side and issue path, projected as details.side and details.issue_path, and the CLI's malformed-capture issue carries observed.issue_path. The first issue path comes from the same selection describeValidationFailure names. * feat(evidence): report source authentication issue paths from the Evidence owner readEvidence and readImmutableEvidence now set the record-relative issue path on their integrity failure, and readEvidencePayload sets it when the caller says where the payload sits. compare_functions passes its side, so a tampered function source reports details.side and details.issue_path like compare_process_captures. Process capture result issue paths are now relative to the Evidence record (normalized_result.*) on both adapters. |
||
|
|
7f2141b568 | refactor(ghidra): take the host from HOST_PLATFORM instead of reading process.platform (#11054) | ||
|
|
c0dd084376 |
refactor(verify): give seven verifier directories' fixture roots to VerifierFixture (#11055)
* refactor(verify): give the android, electron, firmware, ghidra-seed, harmony, inspector and managed verifiers' roots to VerifierFixture Each root is removed only after the MCP clients, transports, owned processes and file handles that may still use it confirm cleanup; a failed cleanup retains and names the root. The verifier-fixture-root baseline shrinks from 90 files / 95 sites to 80 / 85. * fix(verify): keep nested Electron and inspector children owned by the fixture, and plain roots where Windows creates directories The Electron cancellation CLI and application, and each inspector target, now register their stop with the fixture (onceConfirmed keeps the early stop), so the root is removed only after they confirm. The android and inspector verifiers keep a plain directory as before: tools create directories beneath the root, which a private root blocks on Windows. |
||
|
|
3bbdec3fc8 |
test(artifacts): compare ASAR block-integrity limitations with their owning constant (#11061)
Two tests matched three fragments of one limitation sentence, twice for the same row. They now compare the row with BLOCK_INTEGRITY_LIMITATION from AsarListing, beside the existing declared-integrity and hash-status facts. |
||
|
|
b3cba0d762 |
test(process): check each capture provider field once instead of per side (#11067)
The provider admission matrix ran each of the three provider fields for both sides through CLI and MCP. Alternating sides keeps every field and both side labels, and removing the version check or the side label still fails a remaining row. |
||
|
|
1151763582 |
fix(contracts): remove the duplicate advertisedOutputJsonSchema declaration (#11057)
#11005 left two exported declarations of advertisedOutputJsonSchema in src/contracts/toolSchemaMetadata.ts, so main no longer typechecks (TS2451). The second declaration takes an optional target that defaults to the first one's fixed draft-2020-12, so it covers every caller. The first is removed and its documentation moves onto the remaining one. |
||
|
|
08420be3bd |
fix(ghidra): explain Program reuse after startup timeouts
Explain Program reuse in cold-start timeout recovery and distinguish query snapshots from saved Ghidra analysis. Preserve explicit startup-mode selection, first-analysis requirements, and custom-analyzer choices. Refs #10365 Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |