mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 19:23:24 +00:00
fe05a4c56d7294679f286cd0c87cfa4c6a294167
2532
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8110c98c72 |
fix(process): give process-command failures their own recovery instead of doctor (#11101)
* fix(process): give process-command failures their own recovery instead of doctor * test(process): check the delivered process-command recovery instead of banning a word |
||
|
|
a8e472967b |
refactor(process): read Ghidra and Hopper replies through one bounded JSON-line reader (#10699)
* refactor(process): read Ghidra and Hopper replies through one bounded JSON-line reader Both clients now share JsonLineBridgeReader: UTF-8 framing with a mandatory reply line ceiling (bridge.max_reply_bytes, REA_BRIDGE_MAX_REPLY_BYTES, default 256 MiB), one fatal UTF-8 policy, request-id correlation including rejections on the reserved id 0, and typed stream failures. An oversized reply is refused as a transport resource constraint naming the setting and its bytes are discarded. Hopper rejections on id 0 now reach the request on the wire instead of being dropped. Deletes GhidraResponseRouter and HopperResponseStream. * fix(process): bound each bridge reply by the ceiling its own request admitted * fix(process): admit the bridge reply ceiling before launching Hopper or Ghidra * fix(ghidra): keep a refused setting's configuration error through the provider boundary * fix(process): admit both bridge ceilings per request as a typed configuration refusal A malformed REA_BRIDGE_MAX_REQUEST_BYTES or REA_BRIDGE_MAX_REPLY_BYTES seed covered by a runtime override at startup is refused by the runtime view once the override is reset. Hopper and Ghidra read those getters in the request path (and Hopper re-read the request ceiling when a queued request reached the wire, outside the caller's context), so the refusal was thrown instead of returned. Both clients now copy both ceilings once at admission through readRuntimeSetting, return the ConfigurationError (Ghidra as an admission failure), and write queued requests under the ceilings they were admitted with. * refactor(config): read rizin, gdb, Kuna, Ghidra and regex settings through readRuntimeSetting (#10795) Each site caught the ConfigurationError a setting view throws for a malformed launch seed by hand. They now read through readRuntimeSetting and return its Result. GDB reads both debugger limits once per console command and reuses those accepted values for its limitations, timeout and diagnostics instead of re-reading the views after the command ran. Kuna's single-function read returns the refusal after releasing admission instead of throwing it. A counted architecture guard keeps the remaining hand-caught sites from growing. * refactor(hopper): return typed bridge replies from HopperClient.callTool (#10833) * refactor(hopper): return typed bridge replies from HopperClient.callTool The reply contract table existed, but the provider, caller reconciliation and regex search each applied it after callTool returned JsonValue. callTool is now typed by method: it validates the reply against that method's contract and returns the typed reply, or a HopperReplyContractError that names the method and keeps the raw reply. The caller scan keeps that raw reply as its unread page or native result. The provider dispatches list_names, file offsets and the three reconciled operations through their literal methods, and health has its own contract. Transport tests inject a JSON-value table for the fake bridge's own methods. * fix(hopper): refuse value-changing reply contracts and uninstalled methods parseHopperReply returns the raw reply, so a contract whose input and output types differ (a coercion, default or transform) would promise a type the reply does not hold. ValueKeepingContracts refuses such a schema at compile time, for the production table and any injected one. A client whose type argument names a table it was not given now returns AnalysisCapabilityUnavailableError for a method with no installed contract instead of throwing. * refactor(hopper): read the startup handshake through the health reply contract (#10853) parseHopperServerInfo hand-checked each health field that hopperReplySchemas.health already defines. It now parses through that contract, keeps the zod failure as the protocol error's cause, and binds run_id to the launch. * refactor(kuna): read the project deadline through readRuntimeSetting at each request (#10837) * refactor(kuna): read the project deadline through readRuntimeSetting at each request The string, call-graph and xref scans read kuna.project_timeout_ms inside the background producer they start, and the project export read it inside the shared startup promise. A malformed launch seed without an override was thrown from there and reached the caller only through the generic failure mapper; a concurrent waiter that swallows the startup promise's rejection never saw it. Each site now reads the deadline with readRuntimeSetting before starting its work and returns the refusal as that request's value; the export start returns it to each caller that needs the project, and the next request reads it again. * fix(kuna): return a call-graph deadline refusal from analyze_function The dossier reported any relationship failure as unavailable call coverage. A call-graph deadline refusal is the request's own setting failure, so it now returns as that ConfigurationError, as cleanup and cancellation already did. * refactor(kuna): require the accepted project deadline on every export request Remove acceptedExportDeadline's fallback read of the throwing configuration view. KunaProjectRequest and KunaExportRequest now require the deadline the starting operation accepted; the session passes the one it admitted through readRuntimeSetting into #lookupOrBuild. Direct cache callers in tests take it from one shared helper, withKunaProjectDeadline. * test(mcp): carry main's Evidence-format const count (#10995) beside the bridge reply setting's * fix(process): clean Hopper and Ghidra sessions up under the ceilings their start admitted Cleanup requests re-admitted bridge.max_request_bytes and bridge.max_reply_bytes from the current settings. Once an override covering a malformed launch seed was reset, Hopper's shutdown_document and Ghidra's closing checkpoint_program and shutdown were refused before writing, leaving Hopper's document and files or Ghidra's JVM behind. Each session now keeps the ceilings it admitted at start, and its cleanup requests use them. * fix(hopper): reauthenticate for cleanup under the session's admitted ceilings The cleanup reconnect's health handshake still re-admitted the ceilings from the current settings, so a seed refused after an override reset blocked reauthentication and the shutdown after it. It now uses the same session ceilings as the shutdown requests, through one #cleanupLimits accessor. * refactor(process): report an NDJSON line above its ceiling as a limit parse failure Utf8NdjsonOversizeError now extends ParseFailureError<"limit"> (format ndjson, limit ndjson-line-bytes) and keeps the observed bytes the transport error reports, so parseFailureFromCause recognizes it like every other byte-format budget. |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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. |
||
|
|
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> |
||
|
|
7181e7f515 |
perf(mcp): advertise large output union alternatives as shared definitions (#11005)
* perf(mcp): advertise large output union alternatives as shared definitions inspect_analysis_view's advertised output schema held every view result inline in one union definition, which the MCP SDK's default validator compiled into one function: about 1.7 s CPU and 500 MiB peak. Large union alternatives now become definitions of their own and identical definitions are merged, at the owning output projection. Tests that check results against the advertised output contract now compile that schema instead of a separate inline projection, which overflowed the main-thread stack under forked workers. * perf(tests): run source test projects in forked workers (#11016) Thread workers of the source lane share one process, which grew to 3.8-5.0 GiB; forked workers keep each heap separate so the largest process stays near 1.2-1.8 GiB. * test(mcp): select the analysis view contract from its family |
||
|
|
0ddc732c69 |
docs: describe omitted output schemas as the default in README translations (#10658)
* test(mcp): check advertised schemas against a portable dialect in every profile * fix(mcp): re-emit advertised patterns in a portable regex grammar * fix(mcp): present discover_tools input through the selected profile The hot-cold catalog registered discover_tools directly with the SDK, so the default compact input profile still advertised its canonical schema, including page-size defaults clients apply on their own (#5322). Route every listed input schema, transport discovery included, through one server-owned presentation, and pass the selected presentation to the deferred server, which serves recorded tool schemas but not discovery. * fix(mcp): keep the Evidence union on described borrowed inputs borrowEvidenceInput installed its advertised projection on one schema instance. A call site's .describe() rebuilds the schema from its definition, so match_native_functions advertised left and right as unconstrained values in every input profile. Install the projection in the borrowed parser's constructor so derived schemas keep it, for both borrowed inputs and borrowed arrays. * fix(mcp): validate advertised dialect by selected profile * fix(mcp): preserve schema widening through references * feat(mcp): project compact input schemas into the portable advertised dialect One projection (advertisedDialectProjection.ts) owns the compact input advertisement: one type per node, items on every array, string literals as enums, oneOf widened to anyOf, allOf merged, tuples as element unions, exclusive bounds made inclusive, and every keyword outside the dialect dropped. Each rewrite is exact or widening; server validation is unchanged. The root description and sentences for dropped cross-field constraints move to the tool description, which Codex and Zed keep. The compact baseline falls to nullable values only (29), which the dialect cannot express without narrowing an input. The gateway shape repairs (typeArrayItemUnions, hasGatewayIncompatibleShape), the second dependentRequired-to-prose copy and the strict-gateway test denylist are removed; the dialect checker gates the inline presentation instead. * feat(mcp): omit output schemas from tools/list by default No surveyed model API reads an output schema, MCP client validators repeat REA's own result validation, and complete output schemas were about 92% of the default tools/list. REA_MCP_OUTPUT_SCHEMA_PROFILE now resolves to off through one owner (resolveMcpOutputSchemaProfile); compact and full remain selectable. structuredContent is still delivered, and the deferred server serves both off and full from the recorded catalog with the matching recorded identity. Tests and artifact verifiers that validate results against complete advertised output contracts select full explicitly. * docs: describe omitted output schemas as the default in README translations * fix(mcp): select schemas in verification workflows * fix(mcp): refuse zero-padded repeat bounds and record host-specific path patterns * fix(mcp): keep projected schemas permissive * fix(mcp): keep references valid when presentation widens their targets * fix(mcp): keep a single union branch's closure scoped to its properties * fix(mcp): select complete output schemas in the Electron verifier * fix(mcp): select complete output schemas in standalone verifier probes * fix(mcp): keep an allOf member's tuple tail with its own positions * fix(mcp): relax references into negations and conditionals presentation may remove * test(mcp): select the borrowed Evidence contract from its family * fix(mcp): keep astral literals and dynamic references widening in every mode * fix(mcp): omit astral literals and relax untracked references when presentation widens * fix(mcp): select complete output schemas in every verifier transport * fix(mcp): read reference pointers by schema position, not segment spelling * fix(mcp): protect references into collapsing boolean unions and keep referencing branches out of the collapse * fix(mcp): keep reduced schemas open when their root admits names by pattern * test(mcp): keep the reduced-schema pattern case outside the size-limited block * fix(mcp): omit patterns whose classes name astral characters * fix(mcp): decide union collapse and pointer protection from canonical branches * docs(mcp): document non-u astral matching and pin BMP agreement across V8 modes * fix(mcp): keep prototype-named properties as own properties in the dialect projection * test(mcp): select full output schemas in packet and signal schema checks * test(mcp): expect the advertised base64 schema to omit the unbounded pad-bit probe * fix(mcp): protect references into unevaluated keywords lost evaluation removes * fix(mcp): validate the doctor probe reply against the canonical output contract (#10655) * fix(mcp): validate the doctor probe reply against the canonical output contract * test(mcp): replay doctor probe validation under every output profile * test(mcp): accept typed-branch nullable unions in the advertised dialect (#10649) * test(mcp): select full output schemas in HTTP session workflows * fix(mcp): emit stack-safe classes with non-ASCII members and protect draft-07 reference siblings * fix(mcp): protect references into literal siblings of relaxed draft-07 references * feat(mcp): omit output schemas from tools/list by default (#10646) * feat(mcp): omit output schemas from tools/list by default No surveyed model API reads an output schema, MCP client validators repeat REA's own result validation, and complete output schemas were about 92% of the default tools/list. REA_MCP_OUTPUT_SCHEMA_PROFILE now resolves to off through one owner (resolveMcpOutputSchemaProfile); compact and full remain selectable. structuredContent is still delivered, and the deferred server serves both off and full from the recorded catalog with the matching recorded identity. Tests and artifact verifiers that validate results against complete advertised output contracts select full explicitly. * fix(mcp): select schemas in verification workflows * fix(mcp): select complete output schemas in the Electron verifier * fix(mcp): select complete output schemas in standalone verifier probes * fix(mcp): select complete output schemas in every verifier transport * test(mcp): select full output schemas in packet and signal schema checks * fix(mcp): validate the doctor probe reply against the canonical output contract (#10655) * fix(mcp): validate the doctor probe reply against the canonical output contract * test(mcp): replay doctor probe validation under every output profile * test(mcp): accept typed-branch nullable unions in the advertised dialect (#10649) * test(mcp): select full output schemas in HTTP session workflows * fix(mcp): keep the Evidence union on described borrowed inputs (#10597) * fix(mcp): keep the Evidence union on described borrowed inputs borrowEvidenceInput installed its advertised projection on one schema instance. A call site's .describe() rebuilds the schema from its definition, so match_native_functions advertised left and right as unconstrained values in every input profile. Install the projection in the borrowed parser's constructor so derived schemas keep it, for both borrowed inputs and borrowed arrays. * test(mcp): select the borrowed Evidence contract from its family * docs(mcp): admit baseline growth only for restored contract declarations * fix(mcp): state reduced multi-type properties as typed branches, not type lists The reduced fallback derived a property's types and emitted them as a type list, which Gemini, Moonshot and Ark reject. A property whose canonical schema is anyOf string and number therefore traded a typed union for a rejected construct when the inline projection fell back. Emit one type, or anyOf typed branches, so [T, null] becomes the dialect's nullable union. |
||
|
|
4126698407 |
feat(mcp): project compact input schemas into the portable advertised dialect (#10632)
* test(mcp): check advertised schemas against a portable dialect in every profile * fix(mcp): re-emit advertised patterns in a portable regex grammar * fix(mcp): present discover_tools input through the selected profile The hot-cold catalog registered discover_tools directly with the SDK, so the default compact input profile still advertised its canonical schema, including page-size defaults clients apply on their own (#5322). Route every listed input schema, transport discovery included, through one server-owned presentation, and pass the selected presentation to the deferred server, which serves recorded tool schemas but not discovery. * fix(mcp): keep the Evidence union on described borrowed inputs borrowEvidenceInput installed its advertised projection on one schema instance. A call site's .describe() rebuilds the schema from its definition, so match_native_functions advertised left and right as unconstrained values in every input profile. Install the projection in the borrowed parser's constructor so derived schemas keep it, for both borrowed inputs and borrowed arrays. * fix(mcp): validate advertised dialect by selected profile * fix(mcp): preserve schema widening through references * feat(mcp): project compact input schemas into the portable advertised dialect One projection (advertisedDialectProjection.ts) owns the compact input advertisement: one type per node, items on every array, string literals as enums, oneOf widened to anyOf, allOf merged, tuples as element unions, exclusive bounds made inclusive, and every keyword outside the dialect dropped. Each rewrite is exact or widening; server validation is unchanged. The root description and sentences for dropped cross-field constraints move to the tool description, which Codex and Zed keep. The compact baseline falls to nullable values only (29), which the dialect cannot express without narrowing an input. The gateway shape repairs (typeArrayItemUnions, hasGatewayIncompatibleShape), the second dependentRequired-to-prose copy and the strict-gateway test denylist are removed; the dialect checker gates the inline presentation instead. * fix(mcp): refuse zero-padded repeat bounds and record host-specific path patterns * fix(mcp): keep projected schemas permissive * fix(mcp): keep references valid when presentation widens their targets * fix(mcp): keep a single union branch's closure scoped to its properties * fix(mcp): keep an allOf member's tuple tail with its own positions * fix(mcp): relax references into negations and conditionals presentation may remove * test(mcp): select the borrowed Evidence contract from its family * fix(mcp): keep astral literals and dynamic references widening in every mode * fix(mcp): omit astral literals and relax untracked references when presentation widens * fix(mcp): read reference pointers by schema position, not segment spelling * fix(mcp): protect references into collapsing boolean unions and keep referencing branches out of the collapse * fix(mcp): keep reduced schemas open when their root admits names by pattern * test(mcp): keep the reduced-schema pattern case outside the size-limited block * fix(mcp): omit patterns whose classes name astral characters * fix(mcp): decide union collapse and pointer protection from canonical branches * docs(mcp): document non-u astral matching and pin BMP agreement across V8 modes * fix(mcp): keep prototype-named properties as own properties in the dialect projection * test(mcp): expect the advertised base64 schema to omit the unbounded pad-bit probe * fix(mcp): protect references into unevaluated keywords lost evaluation removes * fix(mcp): emit stack-safe classes with non-ASCII members and protect draft-07 reference siblings * fix(mcp): protect references into literal siblings of relaxed draft-07 references * feat(mcp): omit output schemas from tools/list by default (#10646) * feat(mcp): omit output schemas from tools/list by default No surveyed model API reads an output schema, MCP client validators repeat REA's own result validation, and complete output schemas were about 92% of the default tools/list. REA_MCP_OUTPUT_SCHEMA_PROFILE now resolves to off through one owner (resolveMcpOutputSchemaProfile); compact and full remain selectable. structuredContent is still delivered, and the deferred server serves both off and full from the recorded catalog with the matching recorded identity. Tests and artifact verifiers that validate results against complete advertised output contracts select full explicitly. * fix(mcp): select schemas in verification workflows * fix(mcp): select complete output schemas in the Electron verifier * fix(mcp): select complete output schemas in standalone verifier probes * fix(mcp): select complete output schemas in every verifier transport * test(mcp): select full output schemas in packet and signal schema checks * fix(mcp): validate the doctor probe reply against the canonical output contract (#10655) * fix(mcp): validate the doctor probe reply against the canonical output contract * test(mcp): replay doctor probe validation under every output profile * test(mcp): accept typed-branch nullable unions in the advertised dialect (#10649) * test(mcp): select full output schemas in HTTP session workflows * fix(mcp): keep the Evidence union on described borrowed inputs (#10597) * fix(mcp): keep the Evidence union on described borrowed inputs borrowEvidenceInput installed its advertised projection on one schema instance. A call site's .describe() rebuilds the schema from its definition, so match_native_functions advertised left and right as unconstrained values in every input profile. Install the projection in the borrowed parser's constructor so derived schemas keep it, for both borrowed inputs and borrowed arrays. * test(mcp): select the borrowed Evidence contract from its family * docs(mcp): admit baseline growth only for restored contract declarations * fix(mcp): state reduced multi-type properties as typed branches, not type lists The reduced fallback derived a property's types and emitted them as a type list, which Gemini, Moonshot and Ark reject. A property whose canonical schema is anyOf string and number therefore traded a typed union for a rejected construct when the inline projection fell back. Emit one type, or anyOf typed branches, so [T, null] becomes the dialect's nullable union. |
||
|
|
da8f366596 |
fix(mcp): register fx and MCPorter where they read their configuration (#10698)
* fix(mcp): register fx and MCPorter where they read their configuration fx reads $FX_HOME/mcp.json when FX_HOME is set, and MCPorter reads MCPORTER_CONFIG exclusively or prefers an absolute XDG_CONFIG_HOME file. rea mcp add always wrote ~/.fx/mcp.json and ~/.mcporter/mcporter.json, which those clients then ignored. Resolve both from the clients' own rules, and refuse an FX_HOME fx itself refuses. * fix(mcp): detect MCPorter by its selected file and refuse FX_HOME aliases Address review findings: MCPORTER_CONFIG now also names the detection marker, so default registration includes MCPorter when only that file exists, and is resolved with path.resolve as MCPorter does. FX_HOME with . or .. segments is refused, so the private profile mode cannot reach the home folder through an alias. Override tests use the host's path rules for real temporary paths. * fix(mcp): never apply fx's private folder mode to the home folder A linked parent in FX_HOME can name the caller's home folder after the textual root and home checks pass. The private profile writer now compares the opened folder's identity with the caller's home folder and refuses before changing modes or publishing. * feat(setup): let doctor, update and uninstall see MCPorter registrations (#10702) * feat(setup): let doctor, update and uninstall see MCPorter registrations MCPorter becomes a client-table row, so a registration rea mcp add or rea setup --client mcporter wrote is inspected, refreshed and removed like other clients. MCPorter already imports setup-managed clients' registrations, so the row is applicable only through REA's own registration: setup never selects it from detection and doctor reports it only when its file holds a rea row or the caller selects it. A relative MCPORTER_CONFIG is refused because MCPorter resolves it per command directory. * fix(setup): detect MCPorter by the folder of the file it loads With an absolute XDG_CONFIG_HOME and only a legacy ~/.mcporter file, the row returned the legacy file but the absent XDG folder as its detection evidence, so default registration and setup skipped MCPorter. * fix(setup): keep an unresolved client unknown without blocking others' maintenance A client whose configuration location cannot be resolved (for example a relative MCPORTER_CONFIG) is reported as unknown, never missing or absent. Update maintenance leaves each unresolved client out of its scope and names it with its own recovery, while still maintaining the other clients; uninstall still stops, because it cannot tell whether that client's file holds REA's row. * docs(setup): restore MCPorter's release note and client-table row after rebase * fix(update): keep unknown clients in every failed maintenance plan |
||
|
|
422cff00ab |
refactor(process): give POSIX PATH search order one owner (#10891)
* refactor(process): give POSIX PATH search order one owner Program lookup, the packet-tool locator and Jadx's Java lookup each split PATH and resolved empty and relative entries themselves. They now take the candidates from posixPathCandidates in src/process/executableSearch and keep only their own probe and failure reporting. A counted architecture guard keeps new PATH splits from returning; the remaining Windows and Ghidra searches are baselined. * refactor(process): move the colon-split PATH searches onto the search owner REA's launcher-alias lookup and Ghidra's macOS Java lookup split PATH on ":" and skipped relative entries themselves; they now use posixPathCandidates with relativeEntries: "skip", and the guard counts colon splits of PATH as well. * fix(process): produce PATH candidates lazily so an unused entry cannot fail an earlier match * refactor(process): give Windows PATH/PATHEXT search order the executable search owner (#10916) * refactor(process): give Windows PATH/PATHEXT search order the executable search owner * fix(process): keep later PATH entries searchable after a stray quote or a removed working directory * fix(reverse): refuse a Windows objdump or Rizin command that PATH does not find (#10953) * fix(reverse): refuse an objdump or Rizin command Windows PATH does not find instead of launching the bare name * fix(reverse): report a Windows lookup refusal after cancellation and to capability discovery * fix(desktop): search a Windows host's PATH as Windows does when doctor looks up a program programOnPath sent every host through the POSIX PATH search, so on Windows a relative PATH entry reached absoluteCallerPath with platform linux and the Windows working directory, which resolved against itself until the stack overflowed. programOnPath now searches PATH and PATHEXT through windowsPathCandidates on a Windows host, and absoluteCallerPath refuses a non-POSIX working directory with a TypeError instead of recursing. |
||
|
|
e793fd6808 |
feat(mcp): name the next operation when a completed result overflows the response budget (#11015)
* feat(mcp): name the next operation when a completed result overflows the response budget * test(mcp): assert next_operation for every overflow recovery route |
||
|
|
b572dbaf25 | feat(setup): mark a shared enable:false registration as a manual conflict in doctor status (#11019) | ||
|
|
4aefe2daec |
fix(errors): name rea doctor only for providers it can check (#10565)
* fix(errors): name rea doctor only for providers it can check An unclassified ProviderAdapterError, an unreadable result and the final presentation fallback all told the caller to run rea doctor, although doctor checks only hopper, ghidra, ida, jadx, kuna and desktop_build. The doctor scope list moves into the domain so presentation can consult it: covered providers get `rea doctor --provider ID`, others are told plainly that the failure is unclassified and where its reason is reported. Producers whose actionable reason lived only in details.diagnostics now author it: Ghidra's committed-profile conflicts share one owner that says to reopen the target, closed analysis clients share one owner, and a jadx-reported request failure no longer points at provider readiness. The deep-analysis profile rejection names doctor only for doctor-checkable providers. Dead presentation branches for tags handled earlier are removed. * fix(errors): make provider recovery actionable * test(android): remove brittle recovery wording check * test: wait for observed child exit before cancellation * test(errors): check that doctor is not offered instead of matching recovery prose |
||
|
|
babfc87ec0 |
fix(mcp): present discover_tools input through the selected profile (#10592)
* test(mcp): check advertised schemas against a portable dialect in every profile * fix(mcp): re-emit advertised patterns in a portable regex grammar * fix(mcp): present discover_tools input through the selected profile The hot-cold catalog registered discover_tools directly with the SDK, so the default compact input profile still advertised its canonical schema, including page-size defaults clients apply on their own (#5322). Route every listed input schema, transport discovery included, through one server-owned presentation, and pass the selected presentation to the deferred server, which serves recorded tool schemas but not discovery. * fix(mcp): validate advertised dialect by selected profile * fix(mcp): preserve schema widening through references * fix(mcp): refuse zero-padded repeat bounds and record host-specific path patterns * fix(mcp): keep references valid when presentation widens their targets * fix(mcp): relax references into negations and conditionals presentation may remove * fix(mcp): keep astral literals and dynamic references widening in every mode * fix(mcp): omit astral literals and relax untracked references when presentation widens * fix(mcp): read reference pointers by schema position, not segment spelling * fix(mcp): protect references into collapsing boolean unions and keep referencing branches out of the collapse * fix(mcp): omit patterns whose classes name astral characters * fix(mcp): decide union collapse and pointer protection from canonical branches * docs(mcp): document non-u astral matching and pin BMP agreement across V8 modes * test(mcp): expect the advertised base64 schema to omit the unbounded pad-bit probe * fix(mcp): protect references into unevaluated keywords lost evaluation removes * fix(mcp): emit stack-safe classes with non-ASCII members and protect draft-07 reference siblings * fix(mcp): protect references into literal siblings of relaxed draft-07 references * fix(mcp): keep the Evidence union on described borrowed inputs (#10597) * fix(mcp): keep the Evidence union on described borrowed inputs borrowEvidenceInput installed its advertised projection on one schema instance. A call site's .describe() rebuilds the schema from its definition, so match_native_functions advertised left and right as unconstrained values in every input profile. Install the projection in the borrowed parser's constructor so derived schemas keep it, for both borrowed inputs and borrowed arrays. * test(mcp): select the borrowed Evidence contract from its family * docs(mcp): admit baseline growth only for restored contract declarations |
||
|
|
80755a9d16 |
fix(doctor): refuse Ghidra on Windows when REA_GHIDRA_PROJECT_PATH selects an existing project (#10981)
* fix(doctor): refuse Ghidra on Windows when REA_GHIDRA_PROJECT_PATH selects an existing project Runtime refused an existing project on Windows before admission, but doctor did not read REA_GHIDRA_PROJECT_PATH, so it reported Ghidra ready for a registration the provider then refused. The existing-project host check is now part of Ghidra's admission owner; doctor reads the setting from the client's registration and reports a failed existing_project check, and the provider projects the same refusal. An unresolved project path makes doctor's Ghidra answer unknown only on Windows, the one host it affects. * test(ghidra): read the existing-project setting through doctor's system inspection |
||
|
|
27b732e957 |
refactor(kuna): decide Kuna readiness once for doctor and runtime (#10997)
Runtime availability admitted Kuna from its settings and a runnable command, while doctor also required a passing version probe and cache inspection, so doctor could report Kuna unavailable while runtime admitted it. admitKunaCommand is now the one readiness decision: provider availability, the installation inspection and doctor's installation check all project it. Doctor reports the version probe and the cache inspection as separate health checks (version, cache) beside admission; they no longer decide availability, and runtime still does not pay for them. Setup continues to list Kuna as a ready provider only when every check passes. |
||
|
|
26520bd290 |
refactor(providers): finalize apktool and shared artifact resources through runOwned (#10653)
* refactor(providers): finalize apktool and shared artifact resources through runOwned runOwned moves to the provider layer so provider sites can use it without depending on application workflows. It gains a completed-value projection (partial) for values that are not themselves partial observations, an optional signal, and cleanupLeases that bind a close failure to the exact leases whose confirmed release resolves it. ArtifactAnalysisResources.finish is removed; TShark and sigrok finalize through runOwned with the shared release as close. Apktool's hand-written release, cancellation and lease-group composition is replaced by runOwned. A failed primary now keeps a cancellation observed during final cleanup as a secondary failure, as the documented precedence requires. A counted architecture guard refuses new hand-written completed-result abort reclassification outside runOwned. * refactor(adb): finalize runtime-root work through runOwned (#10660) * refactor(adb): finalize runtime-root work through runOwned The ADB runtime-root finalizer re-derived the precedence by hand and kept its own cancellation-with-cleanup combiner. It now runs through runOwned: the work body maps snapshot failures, close releases the root lease and binds its own cleanup error, and partial projects the completed execution. A cancellation whose cleanup fails is now the shared cleanup composite with the cancellation as its primary, as runOwned produces for every other owner. * refactor(providers): keep completed values as diagnostics in runOwned and migrate four finalizers (#10691) * refactor(providers): keep completed values as diagnostics in runOwned and migrate signature, Ghidra, bundle and LLDB finalization * test(providers): run the lifecycle scenarios over every runOwned adopter shape (#10707) One table of testing.md lifecycle rows runs over partial, diagnostics, publishing and lease adopters, replacing the hand-written precedence cases it covers. * chore(lint): move runOwned's classifier baseline entry with the file |
||
|
|
b87b318ae7 |
refactor(wasm): leave WABT cancellation to the shared owners (#10796)
* 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. |
||
|
|
c36649a674 |
feat(managed)!: require managed Evidence fields that were defaulted only for historical Evidence (#10952)
* feat(managed)!: require managed Evidence fields that were defaulted only for historical Evidence Member inspections, comparisons, verification results and application graphs require every field their producers write. nesting_read is boolean and the bare-name comparison mode for historical observations is deleted; signature_resolution loses type-names-v1. The unavailable-metadata member result now writes assembly: null instead of relying on a default. BREAKING CHANGE: managed records missing these fields are refused as malformed; recreate the observation. * docs(managed): drop the remaining historical-omission claims for member Evidence |
||
|
|
3afd8a16ee |
feat(evidence)!: give Evidence bundles a format revision owned by one module (#10861)
* feat(evidence)!: give Evidence bundles a format revision owned by one module `src/domain/evidenceFormat.ts` owns Evidence format evolution. Bundles now carry `evidence_format: 1`; every bundle reader admits only the current revision and refuses an unmarked or other-revision bundle once, with the single recreate-observations guidance, instead of admitting earlier shapes one optional field at a time. The 6.7-era artifact inventory summary identities are no longer rebuilt: compare_artifacts checks the current projection only and reports a mismatch with the owner's guidance. The pre-6.6 identity diagnosis uses the same guidance. SQLite `worker_timeout_ms` and Dart AOT `string_pool.policy`, optional only for historical Evidence, are now required. BREAKING CHANGE: Evidence bundles written by REA 6.x (no `evidence_format`) are refused by import, comparison, reconstruction and analysis-snapshot readers as an integrity mismatch telling the caller to recreate the observations; re-exporting an earlier bundle does not update its format or identities. Bundles constructed by hand must include `"evidence_format": 1`. 6.7-era artifact summaries are refused by compare_artifacts, and SQLite and Dart AOT Evidence without the newly required fields fails validation. * fix(evidence): let the ledger application admit its bundle's format build_reconstruction_obligation_ledger registered the full bundle schema with the SDK, so an unmarked or other-revision bundle was refused as invalid_request before the format owner ran. Register it like coverage: the application parses the request envelope and admits the bundle. * feat(pcap)!: read capture Evidence through the current result schema only (#10879) Delete the pcap read-compatibility schema that defaulted executable identity for historical capture Evidence, and require query_labels_hex (null when unknown) now that every producer writes it. Evidence from an earlier format is refused at the bundle format owner; a record that omits these fields is reported as malformed instead of defaulted. BREAKING CHANGE: inspect_pcap_capture results always carry query_labels_hex, and analysis views no longer default missing tshark/capinfos identity fields. * feat(desktop)!: require the effective view policy in desktop state Evidence (#10886) inspect_desktop_application_state always records the complete policy it used, including sqlite_view_bytes. Drop the optional historical shape and the task draft's absent-policy branch. BREAKING CHANGE: desktop application state results without effective_view_policy, or with a policy missing sqlite_view_bytes, are refused as malformed. * feat(android)!: require component declaration facets and reference aggregates in Android Evidence (#10904) * feat(android)!: require component declaration facets and reference aggregates in Android Evidence The JADX producers always write the manifest component projection with every declaration facet, target_definition and direct_invokes_coverage. Require them, delete the duplicate observed component schema, drop the unknown declaration coverage that only described historical omission, and give manifest view results their explicit facet. BREAKING CHANGE: Android package, component and reference results missing these fields are refused as malformed; component declaration_coverage and its summary counts no longer include unknown; manifest view results always carry facet manifest. * refactor(android): parse package results with the domain schema directly * feat(browser)!: require the DOM length unit and redirect-scoped prior-hop facts (#10897) * feat(browser)!: require the DOM length unit and redirect-scoped prior-hop facts Both CDP producers always declare node_value_length_unit, and the observation session writes redirect_response on every redirect event and no other. Require the unit, drop the diff's absent-unit branch, and admit redirect_response exactly on redirect rows. BREAKING CHANGE: DOM snapshots without node_value_length_unit and redirect timeline rows without redirect_response are refused as malformed, including inline inspections passed to compare_web_captures. * docs(browser): drop the historical redirect_response omission note * feat(native)!: require native Evidence fields that were optional only for historical Evidence (#10946) Mach-O encryption, slice malformed cause, symbol runtime names and import facts; ELF export encoding facts and visibility; value-flow limits; load-image permissions and relocation symbols; Swift type-reference kind and GPU AMD target metadata are required. Legacy enum values (unrecorded, unknown visibility, undecodable, modinfo_field_exceeds_limit) and the retained schemas, view defaults and reinterpretations that served historical Evidence are deleted. BREAKING CHANGE: native records missing these fields are refused as malformed; recreate the observation. |
||
|
|
f8e8dc3e7a |
feat(cutter): name the plugin re-copy recovery for sessions whose plugin source is unknown or modified (#10950)
* feat(cutter): name the plugin re-copy recovery for sessions whose plugin source is unknown or modified * test(cutter): assert recovery names the owner's platform plugin path |
||
|
|
d0fee4e58e |
fix(mcp): re-emit advertised patterns in a portable regex grammar (#10582)
* test(mcp): check advertised schemas against a portable dialect in every profile * fix(mcp): re-emit advertised patterns in a portable regex grammar * fix(mcp): validate advertised dialect by selected profile * fix(mcp): preserve schema widening through references * fix(mcp): refuse zero-padded repeat bounds and record host-specific path patterns * fix(mcp): keep references valid when presentation widens their targets * fix(mcp): relax references into negations and conditionals presentation may remove * fix(mcp): keep astral literals and dynamic references widening in every mode * fix(mcp): omit astral literals and relax untracked references when presentation widens * fix(mcp): read reference pointers by schema position, not segment spelling * fix(mcp): protect references into collapsing boolean unions and keep referencing branches out of the collapse * fix(mcp): omit patterns whose classes name astral characters * fix(mcp): decide union collapse and pointer protection from canonical branches * docs(mcp): document non-u astral matching and pin BMP agreement across V8 modes * test(mcp): expect the advertised base64 schema to omit the unbounded pad-bit probe * fix(mcp): protect references into unevaluated keywords lost evaluation removes * fix(mcp): emit stack-safe classes with non-ASCII members and protect draft-07 reference siblings * fix(mcp): protect references into literal siblings of relaxed draft-07 references |
||
|
|
d044f44d91 |
feat(setup): inspect, refresh and remove five mcp-add-only clients (#10694)
* feat(setup): give five mcp-add clients one client-table row Cline VS Code extension, Kiro, Mastra Code, Zed and Amp move from registration-only catalog entries to rows in the client table. rea mcp add projects those rows, so doctor, update and uninstall now inspect, refresh and remove what it wrote, and setup offers each client when detected. Refs #7181 * refactor(setup): keep FreeBuff's comment on its declaration The client helpers added for the folded mcp-add clients were inserted between FreeBuff's profile-directory comment and its declaration. Move them above it, and drop an import the folded locations no longer use. * test(setup): refresh an older mcp-add registration through setup Address review: seed each folded client with an older REA-owned package runner launcher, then check that doctor reports it stale, update selects it, setup plans and applies the update, and doctor then reads the current launcher. * fix(setup): register Amp in settings.jsonc when that is its settings file (#10717) Amp reads ~/.config/amp/settings.json or settings.jsonc. REA always used settings.json, creating a second file beside an existing settings.jsonc. Use settings.jsonc when it is the only file, and refuse when both exist because Amp does not document which one it reads. * feat(setup): manage Cline in VS Code Insiders, VSCodium, Cursor and Windsurf (#10729) * feat(setup): manage Cline in VS Code Insiders, VSCodium, Cursor and Windsurf The Cline extension keeps its MCP settings in the global storage of whichever editor runs it. REA resolved only VS Code's, so a Cline in another editor was never configured, inspected or cleaned. Add one client-table row per editor, resolved through the shared Code-OSS user data rule, and detected where that editor's Cline settings exist. * test(setup): cover VSCODE_PORTABLE for Cline's editor hosts Address review: VSCODE_PORTABLE moves only VS Code's own storage, so the other editors keep their settings path; and the older-release note now says which hosts mcp add could register before. * fix(setup): find a Linux Flatpak Zed's configuration (#10721) * fix(setup): find a Linux Flatpak Zed's configuration Zed's config_dir honors FLATPAK_XDG_CONFIG_HOME first, and a Flathub Zed reads ~/.var/app/dev.zed.Zed/config/zed inside its sandbox. REA always wrote ~/.config/zed, which that Zed never reads. Honor the override, use the sandbox folder when it is the only one, and refuse when both a native and a Flatpak configuration exist. * fix(setup): treat an XDG_CONFIG_HOME naming the Flatpak folder as one Zed folder * fix(setup): treat linked native and Flatpak Zed folders as one configuration * test(setup): expect doctor to report the Amp registration mcp add wrote |
||
|
|
8428de13d3 |
feat(ida)!: require an explicit protocol for attached IDA registrations (#10846)
* feat(ida)!: require an explicit protocol for attached IDA registrations An attached registration (the default mode) silently selected the legacy ida-pro-mcp 1.4 GUI proxy when `protocol` was omitted. The registration schema now resolves the upstream protocol once: attached registrations must name `"legacy"` or `"native"`, headless registrations resolve to the database supervisor, and consumers read the resolved protocol instead of inferring it from `mode`. BREAKING CHANGE: an attached IDA registration without `protocol` is refused with a configuration error naming the choice. Add `"protocol": "legacy"` to an ida-pro-mcp 1.4 proxy registration (or `"protocol": "native"` for the ida-free-mcp plugin). Headless registrations are unchanged. * test(ida): name the protocol in every attached registration fixture The setup budget fixture still wrote an attached URL registration without a protocol, and the IDA registration rejection fixtures relied on the missing protocol as one of several failures. Each now names its protocol, so setup reaches its timeout checks and every rejection case fails only for its own constraint. |
||
|
|
66d1527a3d | refactor(native): parse native inventory results once at the operation port (#10880) | ||
|
|
17a5f14f98 |
fix(process): run ps from fixed system locations, not REA's PATH (#10755)
* fix(process): run macOS ps from /bin/ps, not REA's PATH Owned process cleanup and process sampling ran "ps" through REA's PATH, so an unusable PATH turned a confirmable cleanup into an incomplete one (spawn ps ENOENT). macOS ships ps at /bin/ps on the sealed system volume. Linux keeps the documented procps-on-REA's-PATH contract. * test(process): stop the ps fixture only after its descendant spawned * fix(process): run Linux ps from fixed system locations before REA's PATH Linux process ownership now runs the first executable of /bin/ps, /usr/bin/ps and /run/current-system/sw/bin/ps, searching REA's PATH only when none exists. Admission refusals name the ps that ran in their reason and ps_command/ps_source diagnostics; cleanup failure reasons keep the executed command. Doctor and remediation text follow the same selection. The macOS cleanup test now releases its fixture group even when the descendant wait fails. * fix(application): keep which ps ran in provider availability ownedProcessPrerequisiteAvailability copied only the admission and system codes from a Linux ps refusal, so Ghidra, JADX and Apktool status lost ps_command and ps_source. Copy the refusal's prerequisite facts from one key list. |
||
|
|
6a4caa065b |
refactor(providers): classify raw provider failures through one owner (#10757)
* 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. |
||
|
|
3b17d05f9d |
docs(adr): accept parsing native operation facts once at the operation port (#10866)
* docs(adr): propose parsing native operation results once at the operation port * docs(adr): accept parsing native operation facts once at the operation port |
||
|
|
c06a0b9ee8 |
feat(pcap): read tshark JSON packets through one envelope owner with an adjustable expansion bound (#10788)
* refactor(pcap): read tshark JSON packets through one envelope owner PcapOutput and the packet-capture reader each decoded tshark -T json and checked the packet envelope. The capture reader let SyntaxError escape and accepted any shape until its field schema ran. src/pcap/TsharkJsonPackets.ts now owns the envelope (malformed JSON, the packet array, each packet's _source.layers) as typed failures, and the pcap byte and expansion budget. Both consumers map those failures to their existing error kinds. An architecture guard keeps _source.layers reads in the owner. * fix(captures): keep producer output on a refused packet reply parsePacketOutput threw AnalysisOutputError itself, so the provider's failure mapping returned it without the captured stdout and stderr, both for envelope refusals and for unordered or out-of-limit frames. It now returns a Result with the reason and cause, and the provider builds the AnalysisOutputError with capturedOutput. * feat(captures): bound packet-capture JSON expansion by an adjustable setting The capture path parsed TShark's selected-field JSON without the expansion estimate the pcap reader charges. It now reads through readTsharkJsonPackets under capture.packet_json_expansion_bytes (REA_CAPTURE_PACKET_JSON_EXPANSION_BYTES). The estimate charges at most 130 bytes per code unit and the output is one Node string, so no admissible output reaches 69,793,215,440 bytes; the default and maximum are 128 GiB, so the budget refuses only when lowered. A refusal is an adjustable_budget resource constraint naming the setting and keeps the producer output; a malformed launch seed is refused before the capture is read. |
||
|
|
b0e32578ae |
feat(cli): warn after mcp add writes Claude Desktop's configuration (#10696)
* feat(cli): warn after mcp add writes Claude Desktop's configuration rea mcp add resolves Claude Desktop from the client table, whose row says a running app can rewrite its configuration from memory, but the command never told the caller. Print that notice on stderr when it writes the file. Backup notices now use the client's display name instead of special-casing Amp. * fix(cli): warn about Claude Desktop whenever mcp add wrote its file Address review findings: a registration that failed after publication, such as cancellation during verification, still left the file written, so the running-app notice now follows the registration owner's written fact instead of overall success. The CLI test compares the delivered notice with its owner instead of freezing the sentence. |
||
|
|
4b31661441 |
fix(plist): surface repeated dictionary keys in every plist reader (#10781)
* fix(plist): surface repeated dictionary keys in keyed archive, Interface Builder, entitlement and Info.plist readers * test(plist): cover repeated keys in Interface Builder archives and entitlements (#10797) |
||
|
|
c296c91770 |
fix(apktool): report the decoder JVM's heap exhaustion as memory, not a target refusal (#10634)
* 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(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. |
||
|
|
fa53f7070a |
refactor(cli): project view-delivery inspectors from their contracts (#10600)
* refactor(cli): project view-delivery inspectors from their contracts * refactor(cli): project APK signature, desktop application and EVM inspectors from contracts (#10603) |
||
|
|
a395104168 |
fix(artifacts): report ZIP bytes the central directory does not account for (#10580)
* fix(artifacts): report ZIP bytes the central directory does not account for * fix(artifacts): validate ZIP accounting and join traversal * fix(artifacts): match an unsigned ZIP data descriptor whose CRC equals the signature The optional descriptor signature only adds a candidate layout; both layouts are checked against the recorded CRC and sizes. * fix(artifacts): keep ZIP close observable and account AES data descriptors Close joins running traversal steps instead of returning the traversal, so a caller's next step after close still rejects as unavailable. Member accounting reads through BinaryReader, and a data descriptor whose directory reports no CRC (AE-2) is matched on its sizes. |
||
|
|
1f7884b5b9 |
refactor(process): classify owned command outcomes through one owner (#10628)
* 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(pcap): attribute a limited capture's exit through the prlimit wrapper * 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 * 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 |
||
|
|
52d6725d63 |
fix(cutter)!: report undeclared output truncation and document generation as unknown (#10726)
* fix(cutter)!: report undeclared output truncation and document generation as unknown cutter_command filled a missing output_truncated with false and a missing document_generation with the caller's expected_generation, so a reply that did not declare them read as "nothing omitted" and "document unchanged". Both are now null when the plugin did not declare them, with an Evidence limitation for each. A command that never started still reports output_truncated false, because there was no output to omit. The packaged plugin now declares output_truncated on every command reply and the current generation on its not-started replies. BREAKING CHANGE: cutter_command's result fields output_truncated and document_generation are now nullable. A caller that read document_generation as a number must handle null by listing Cutter sessions again before choosing an expected_generation. A caller that read output_truncated as a boolean must treat null as "the output may be incomplete". * test(cutter): cover the unknown-truncation limitation |
||
|
|
0c38229dd3 |
feat(cutter): identify the running plugin's source and refuse a modified one (#10731)
* feat(cutter): identify the running plugin's source and refuse a modified one The Cutter plugin now publishes the SHA-256 of its own file on its session descriptor (an additive field). Discovery reports each session's bridge_source as packaged, modified, or unknown (an older plugin without the field). cutter_command refuses a modified plugin before sending anything and names the packaged plugin to copy into Cutter's plugins/python directory. * fix(cutter): report an unreadable packaged plugin instead of hiding the live session * test(cutter): give the discovery fixture sessions their bridge source |
||
|
|
12dd3d38ac |
fix(artifacts): honor record-and-continue for lipo and FAT slice disagreement (#10732)
* fix(artifacts): honor record-and-continue for lipo and FAT slice disagreement * fix(artifacts): keep recovered slice names distinct, lipo field evidence, and unknown coverage without a FAT parse * fix(artifacts): keep lipo's unnormalized CPU declarations when FAT ranges are authoritative |
||
|
|
4673457de2 |
fix(plist): record dictionary keys declared more than once (#10737)
* fix(plist): record dictionary keys declared more than once before decoding collapses them * fix(plist): bound repeated key names in the limitation and mark only real omissions |
||
|
|
a090fa7098 |
fix(il2cpp): report the exceeded native-link maximum in the public refusal (#10741)
* fix(il2cpp): report the exceeded native-link maximum in the public refusal * fix(il2cpp): report each native-link budget's maximum in the unit its producer counts * refactor(elf): report pointer relocation failures through ParseFailure (#10748) |
||
|
|
2e1e6593f2 |
refactor(application): own the finalization precedence in runOwned (#10645)
* refactor(application): own the finalization precedence in runOwned runOwned runs owned work, closes its owner and applies the documented precedence once: a recorded failure stays primary, cancellation before commit keeps the completed value as a partial observation, cancellation after commit keeps the value, and unconfirmed cleanup reports cleanup_incomplete while keeping the completed value. finishAnalysisCommand now projects its Finalized outcome; its 31 callers are unchanged. * fix(application): preserve finalization outcomes * fix(application): classify finalization by the primary error and keep cancellation through recovered publication A producer composite whose primary is a cancellation finalized as failed because the kind read only the top-level error class; it now follows primaryAnalysisError. A cancellation that arrived while a recovered value's publication failed was dropped because the signal was read before that last await; it is now attached to the publication failure as a secondary. * fix(cli): keep the initial failure snapshot whenever close itself succeeded |
||
|
|
89640a446a |
fix(parsers): stop reading every RangeError as a format failure (#10602)
* refactor(parsers): report format failures through one ParseFailure algebra Add ParseFailure (malformed, truncated, unsupported, limit, with format, offset and field) and its one carrier, ParseFailureError, in the domain. BinaryReader now names truncation and the field it read, and its native format and resource failures are ParseFailureError subclasses. Providers projected a format failure with their own instanceof ladder, and some dropped the selected path from the invalid_format message. parseFailureAnalysisError now owns that projection for the native, Go, devicetree, V8, Windows Shortcut and Electron fuse providers. The V8 code cache, Windows Shortcut and Electron fuse format classes are removed in favour of the algebra. The architecture guard counts raw Buffer and DataView reads, plain Error throws in parser folders and plain JSON.parse of parser input against baselines that can only shrink. * fix(parsers): stop reading every RangeError as a format failure Mach-O, Swift and Objective-C metadata parsers threw RangeError for a truncated or malformed record, so their catch sites treated any RangeError as a partial decode: a call stack overflow or a host string limit became an "unresolved" metadata reason, and the IL2CPP Mach-O path reported it as a malformed container. Those parsers and the CIL method body reader now throw ParseFailureError. hostRangeErrorKind is the one interpreter of a host RangeError (stack overflow, host capacity, raw out-of-bounds read), and parseFailureFromCause admits only a parse failure or a raw out-of-bounds read as evidence about the input. Fixup stream catch-alls rethrow host limits. The architecture guard counts the remaining direct instanceof RangeError checks. * fix(parsers): preserve Apple metadata failure ownership * test(architecture): shrink parser failure baseline * fix: preserve uncertainty for host range errors |
||
|
|
da53dce1f7 |
refactor(cli): project Go, V8 and delivery inspectors from their contracts (#10576)
Migrate inspect-go-binary, inspect-v8-code-cache, inspect-devicetree and inspect-native-exports onto the contract command description and delete their hand-written options and input spreads. The description gains evidenceDelivery. It adds the shared --detail and --evidence_output options, and the run context carries the selected delivery. A contract detail field selects that delivery and is not passed to the analysis, as the hand-written commands did. Go's cross-field budget rules stay with the service's contract parse, so standalone --max-string-literals still returns invalid_request. The parity guard accepts the declared CLI-only delivery options as the only options without a contract field. |
||
|
|
6c062c9c2a |
fix(setup): stop writing the default compact input profile for Kimi and LM Studio (#10559)
* fix(setup): stop writing the default compact input profile for Kimi and LM Studio The server already advertises compact input schemas when REA_MCP_INPUT_SCHEMA_PROFILE is unset, so setup no longer adds that value to Kimi Code and LM Studio registrations, and doctor/status no longer report a registration without it as stale. Explicit stored or setup-environment profiles are still preserved. Refs #10514 * fix(setup): validate LM Studio registration environment * test(hopper): retry cleanup after confirmed application exit |
||
|
|
a22fb6e60b |
fix(model): report malformed GGUF and Safetensors headers as invalid_format through ParseFailure (#10667)
* refactor(model): report GGUF and Safetensors format failures through ParseFailure * fix(model): report malformed model headers as invalid_format through the shared mapping Malformed and truncated GGUF and Safetensors headers now take the shared ParseFailure mapping (invalid_request, invalid_format on path) instead of the model provider's own BinaryTargetError file_format_rejected. Unsupported forms stay unsupported_target and model allowances keep their resource-constraint recovery. |
||
|
|
2705aad365 |
fix(il2cpp): select universal binary slices through the shared Mach-O selection (#10661)
* fix(il2cpp): select universal binary slices through the shared Mach-O selection * test(il2cpp): assert selection facts instead of full sentences |