mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 19:23:24 +00:00
90e192240ab0166effd9fadd1ecb80841dcf0dc2
2063
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
271e375924 |
refactor(application): read the host from HostPlatform in the remaining application modules (#11124)
Scenario planning and plan Evidence take a required platform. Host file operations (target resolution, output trees, Windows spelling lookup, executable checks, native snapshot admission), the Linux distribution read and the process CLI adapter read HOST_PLATFORM explicitly. ByteEntropyService takes an optional platform seam, so its Windows casing test injects win32 instead of stubbing process.platform. src/application no longer reads process.platform or process.arch. |
||
|
|
5c53bcaed8 |
feat(mcp)!: retire the full schema profiles and declare schema facts as typed annotations (#10693)
* 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 * refactor(contracts): declare root discriminators as typed schema annotations * 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. * feat(mcp)!: retire the full schema profiles and declare complete observations as a typed annotation (#10718) * refactor(mcp): declare complete observations as a typed annotation applied only on the wire * test(mcp): compare complete-observation declarations with their owning text * refactor(schema): couple Zod checks with their JSON Schema constraint keywords (#10725) * refactor(schema): couple Zod checks with their JSON Schema constraint keywords * refactor(schema): declare pattern approximations and object output roots as typed annotations (#10754) * refactor(schema): declare pattern approximations and object output roots as typed annotations * fix(schema): refuse pattern declarations JSON Schema cannot state * test(schema): select guided_workflows from its contract family * feat(mcp)!: retire the full input and output schema profiles (#10841) * feat(mcp)!: retire the full input and output schema profiles The compact input presentation is now the only advertised input schema, and output schemas are either omitted (`off`, the default) or bounded (`compact`). Catalog identity, the build-recorded digests and the recorded startup catalog collapse to those presentations: two digest profiles instead of six, one recorded catalog instead of two, and no input dialect baseline. Tests and verifiers that validated replies against listed full output schemas now validate against the canonical output contract, which REA already enforces server-side; tests that asserted canonical input restrictions read the canonical input schema instead of a full listing. BREAKING CHANGE: `REA_MCP_INPUT_SCHEMA_PROFILE=full` and `REA_MCP_OUTPUT_SCHEMA_PROFILE=full` are refused at startup and by `rea setup` with a configuration error naming the setting. Remove the setting from the client registration (or rerun setup with `REA_MCP_INPUT_SCHEMA_PROFILE=compact` / `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact`). `REA_MCP_INPUT_SCHEMA_PROFILE` still accepts `compact`. Server-side validation is unchanged. * test(mcp): validate replies against canonical output contracts at every listed-schema reader tools/list omits output schemas by default, so fixtures, verifiers and the Android analysis runners that read a listed outputSchema now bind the canonical contract instead. connectLocalToolsMcp and advertisedMcpToolSchemas hand the SDK a definition carrying the canonical output schema, so the SDK client and caller-supplied validators check every successful reply. * test(mcp): resolve Android runners' output contracts from the selected repository The Android efficiency runners imported the canonical output-schema helper from the harness checkout while --repository selects the revision under test. Import it from the selected repository, as the runners already do for the SDK and Ajv. * test(mcp): let Android runners compare revisions before the canonical output helper A selected revision without scripts/lib/canonical-output-schema.mjs could not start the Android runners. Choose the output contracts in one harness helper: the selected revision's canonical contracts when it has them, otherwise its listed schemas under the full output profile it still supports. * fix(scripts): keep caller launch settings when the real Hopper verifier builds its server environment The verifier deleted REA_VERIFY_SERVER_COMMAND and REA_VERIFY_SERVER_ARGS_JSON from process.env itself before reading them, so a caller selecting an installed REA command silently ran the checkout's dist/main.js. Copy the environment, as main does, so only the child's environment changes. * test(mcp): validate whole replies against canonical output contracts wherever a listed definition is held tools/list omits output schemas by default and the full output profile is gone, so tests that handed the SDK a listed definition no longer checked complete replies. Attach the canonical output schema with withCanonicalOutputSchema at every held REA tool definition. Environment-served tools (not REA contracts), and the deferred-runtime and doctor tests that exercise per-profile listings, keep their listed definitions. * test(mcp): record the advertised catalog summary without the retired full profiles Retiring the full input and output profiles leaves only the compact input and compact output listings, so the summary drops the full-profile digests and every pattern only the full listings carried. Regenerated with npm run verify:advertised-schemas -- --update-summary. |
||
|
|
3e4e178ccc |
refactor(setup): take the platform in client configuration readers and the setup write path (#11120)
* refactor(setup): take the platform in client configuration readers and the setup write path ClientRegistrationEnvironment, ClientConfigurationFiles and SupportedClients take a required platform (before defaulted parameters). Setup's configure, inspect and alignment entry points take the setup host's platform and pass it through every layer read, ownership check and the Cordis serializer, which now aliases Windows environment names by the selected platform instead of the running host. Host file operations in ClientConfigPath, ClientConfigurationPublication, JsonFiles and rea mcp add read HOST_PLATFORM explicitly. * fix(setup): keep private-profile modes on the host when setup selects another platform |
||
|
|
4bd578cc08 |
refactor(views): give complete-within-view coverage only the returned count (#11132)
* refactor(views): give complete-within-view coverage only the returned count * test(views): keep only the item-view coverage assertion whose fixture distinguishes it |
||
|
|
682a57a987 | fix(native): keep Objective-C class import coverage partial when candidate completeness is unstated (#11128) | ||
|
|
28d28b0578 |
refactor(setup): take the platform in doctor, setup, uninstall and update maintenance (#11082)
* refactor(setup): take the platform in doctor, setup, uninstall and update maintenance * test(setup): cover a caller-selected platform in update maintenance |
||
|
|
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 |
||
|
|
39537b95af | refactor(reverse): let objdump and Rizin own their Evidence limitations and name the provider a deadline bounded (#11113) | ||
|
|
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. |
||
|
|
7134053d27 |
feat(artifacts): name integrity checks for DMG, directory and release-exposure readers (#11056)
* feat(artifacts): name integrity checks for DMG, directory and release-exposure readers Directory members and release-exposure members whose file identity or bytes changed since inventory report member-identity; a directory entry without captured state reports entry-metadata and a changed directory root container-identity; an hdiutil checksum failure reports image-checksum. AnalysisArtifactChangedError carries the check from the reader failure and projects it as details.integrity_check. * fix(artifacts): name missing directory entry state and keep integrity checks through error copies * feat(artifacts): name integrity checks for ZIP, PyInstaller and changed release files (#11081) feat(artifacts): name integrity checks for ZIP, PyInstaller and changed release files, and keep them through reader projections * feat(artifacts): name integrity checks for the remaining readers and their projections (#11098) |
||
|
|
97ffa67f84 |
refactor(setup): require the platform in client-layer readers and private-profile helpers (#11074)
* refactor(setup): require the platform in client-layer readers and private-profile helpers * refactor(setup): drop the client-layer readers' unused host import |
||
|
|
ce9bdc526a |
fix(agentenv): settle cancelled long runs and preserve teardown receipts (#11095)
Bound AgentEnv long-run cancellation, preserve partial command facts and complete computer teardown before resolving retained jobs. Includes the supervisor and cleanup implementation from #10675 plus polled-receipt and explicit-unknown exit-status fixes. Validation: 14 Python controller tests, 31 host tests and 30 compiled MCP/lifecycle tests passed. Static, documentation and discovery checks passed. Real AgentEnv deployment was not exercised: runner unavailable. Fixes #10676 Related: #10675 Co-authored-by: Adolanium <94890352+Adolanium@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
7dd24dc08c |
feat(evidence): report comparison constraints, remaining issue counts and observed workflows as fields (#11078)
* feat(evidence): report comparison-source constraints, remaining issue counts and observed workflows as fields * fix(evidence): locate snapshot bundle schema issues within the snapshot document * test(evidence): check each comparison-input mismatch and terminal omission once (#11087) |
||
|
|
df1e647266 |
refactor(desktop): let build-computer and agentenv cleanup errors read their owner's release (#10855)
* refactor(errors): read cleanup completion from dependencies instead of pushing it to dependents AnalysisError.cleanupIncomplete becomes a getter over the error's own unresolved state and its bound dependencies. The WeakRef dependents graph and resolveCleanup's push propagation are removed, and subclasses mark their initial state through markCleanupIncomplete instead of overriding a public mutable field. * fix(errors): settle bound dependencies before binding more A composite whose dependencies had released but whose status was never read stayed incomplete when a later dependency was bound. * refactor(errors): let errors read a lease group's release instead of resolving them (#10759) AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink (#10763) * refactor(errors): let errors read a lease group's release instead of resolving them AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink * refactor(process): let worker cleanup errors read their root epoch's release OwnedWorkerRuntime's root epoch is now an AnalysisCleanupReleaseClaim. Errors bound to it read its release when asked instead of the epoch pushing resolveCleanup() through weak references, and a runtime without a retained root binds an already-released owner. Removes the OwnedWorkerCleanupFailure structural type and four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(pcap): let pcap cleanup errors read command and snapshot release (#10792) Retained pcap commands, retained snapshot failures and snapshot completion descriptors now own their release and errors read it: commands and snapshot failures implement AnalysisCleanupReleaseClaim, and a failed completion-descriptor close is retried through an AnalysisCleanupLease bound to its error. Removes four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(process): let Darwin helper cleanup errors read their owner's release Darwin helper cache and run-token reader root cleanup now record an AnalysisCleanupRelease that every failure reports; a successful retry confirms it. Replaces the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes two resolveCleanup() and two bindCleanupDependencies() calls; both counted baselines shrink. * refactor(ghidra): let Ghidra cleanup errors read the client's and checkpoint's release GhidraClient and GhidraCheckpoint bind each cleanup failure to an AnalysisCleanupRelease and confirm it when a later close or retry releases everything, instead of keeping a set of failures and pushing resolveCleanup() to each. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(process): let debugger session cleanup errors read a confirmed stop OwnedDebuggerSessionRegistry binds each retained gdb or rizin cleanup failure to the session's AnalysisCleanupRelease and confirms it when a stop is confirmed, keeping the latest failure for retry reporting, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): drop the debugger registry's unused closeOperation option Returning the latest retained failure removed the last reader of closeOperation; remove the option and the values gdb and rizin supplied. * refactor(server): let environment shutdown errors read a successful close serveEnvironment binds each shutdown failure to an AnalysisCleanupRelease that a later successful close confirms, instead of pushing resolveCleanup() to a set of failures. The state-file retry test now also requires the earlier report to read the release. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): release retained screen-judge cleanup through its lease Each retained judge or screenshot cleanup owner is wrapped in an AnalysisCleanupLease bound to its failure; close() releases the lease, which records the release the failure reads, instead of closing the owner and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(ida): let IDA close failures read the session's later close IdaSessionClient's close failure binds an owner that is both its resource owner and its release claim, read from the client's closed state, instead of keeping weak references and pushing resolveCleanup() after a successful retry. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(javascript): let source-map codec cleanup errors read a later close (#10814) * refactor(javascript): let source-map codec cleanup errors read a later close OwnedCodec binds each close failure to an AnalysisCleanupRelease that a later successful close confirms, replacing the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes one resolveCleanup() and one bindCleanupDependencies() call; both counted baselines shrink. * refactor(cutter): let pending Cutter command errors read the completion receipt (#10815) * refactor(cutter): let pending Cutter command errors read the completion receipt Each pending Cutter command keeps an AnalysisCleanupRelease bound to its timeout failure; the producer's terminal completion receipt confirms it instead of pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(application): let provider candidate cleanup errors read the candidate's close (#10817) * refactor(application): let provider candidate cleanup errors read the candidate's close AnalysisProviderRegistry keeps one AnalysisCleanupRelease per candidate whose resource close is unconfirmed; failures bind to it and a later confirmed close confirms it, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * fix(errors): bind a cleanup release claim to an error at most once AnalysisError kept release claims in an array, so a provider whose retried close returned the same error bound the same claim again on every retry and each cleanupIncomplete read scanned the duplicates. Keep the claims in a set. * refactor(application): let reverse-tool cleanup errors read a verified stop (#10819) * refactor(application): let reverse-tool cleanup errors read a verified stop Each retained provider process group in ReverseEngineeringService keeps an AnalysisCleanupRelease; its command and retry failures bind to it and a later verified stop confirms it, instead of collecting failures and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(sqlite): let SQLite worker and root cleanup errors read their release (#10821) Each retained SQLite snapshot cleanup records an AnalysisCleanupRelease for its worker and for its runtime root; the resource failures bind to them and a verified stop or root removal confirms them, instead of pushing resolveCleanup(). Composite failures keep reading those resource failures. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(android): let JADX cleanup errors read their retained cleanup's release Each retained JADX cleanup records an AnalysisCleanupRelease for the admission failure's descriptor owners and one for the whole retained cleanup. The admission failure and every error the cleanup reports bind to them, and a confirmed close confirms them, instead of pushing resolveCleanup() through WeakRefs to reported errors. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let session close failures read the client's later close A retained session cleanup records an AnalysisCleanupRelease; unowned cleanup failures the client's close reported bind to it and the successful close confirms it, instead of the session collecting them and pushing resolveCleanup(). Failures that already follow their own owner keep reading it. Adds a regression for an unowned close failure. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): let build-computer and agentenv cleanup errors read their owner's release Build-computer teardown, retained task readers, remote reader folders and agentenv solve sandboxes each record an AnalysisCleanupRelease that their bound failures read; a verified teardown or stop confirms it instead of pushing resolveCleanup() through WeakRef sets. Long-run job failures read whether every job they name has confirmed its stop, so a failure naming two jobs no longer reads complete when only one stops (regression added). WeakRef sets kept only where late facts (completion receipts, reader views) are still retained as diagnostics. Removes six resolveCleanup() calls; the counted baseline shrinks. * refactor(kuna): let source-map and Kuna cache cleanup errors read their owner's release (#10856) * refactor(browser): let late source-map fetch errors read their response's release A pending source-map fetch and a response cancellation each record an AnalysisCleanupRelease that their cancellation or deadline failure reads; releasing the late response or the reader lock confirms it instead of pushing resolveCleanup(). Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(kuna): let project-cache cleanup errors read each owner's release Each retained Kuna resource owner (process, staging, hash descriptor, retired file) records a release that the errors reporting it read; an error completes once every owner it reports confirms, and retirement that moves staging to a retained file forwards the staging owner's release to the file's. Replaces the WeakRef report list, its pruning and the resolveCleanup() push. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): forbid resolveCleanup() pushes; native markers read their supervisor's release (#10857) * refactor(providers): let an attributed client failure read its source's completed cleanup Re-attributing a failure whose source cleanup already completed now binds a claim reading that source's release instead of pushing resolveCleanup() onto the new error; a pending source is still bound as a dependency. Resources stay as history, as before. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): let native command markers read their supervisor's release ProviderProcessSupervisor records an AnalysisCleanupRelease that a stop proving the process ended confirms. Native command and LLDB resolver cleanup markers bind to their supervisor's release, so a verified stop by either owner completes them, instead of each owner pushing resolveCleanup() onto the markers it tracks. Removes the last two resolveCleanup() calls outside the error base; the counted baseline is empty. * chore(verify): forbid resolveCleanup() pushes outside the error base Every production owner now confirms a release its errors read, so the counted baseline is empty. The guard becomes an outright ban with no baseline entry. * test(native): complete native command and LLDB markers through a direct supervisor stop * refactor(errors): complete an error's cleanup from its owner's record and every dependency (#10892) * refactor(errors): complete an error's cleanup from its owner's record and every dependency * refactor(errors): complete test errors through an owner release and delete resolveCleanup() (#10898) * refactor(android): compose JADX and Apktool cleanup failures through one shared owner (#10900) * refactor(android): compose JADX and Apktool cleanup failures through one shared owner * refactor(application): compose service cleanup failures through the shared owner (#10902) |
||
|
|
7826e9688d |
refactor(reverse): fake objdump and Rizin commands only through the owned supervisor (#11076)
* refactor(reverse): fake objdump and Rizin commands only through the owned supervisor * test(reverse): fake launch refusals and failed exits as the owned supervisor reports them * refactor(reverse): name objdump and Rizin command repairs through the command port (#11080) |
||
|
|
cabd56ea71 |
refactor(domain): give strict UTF-8 decoding one owner with an explicit BOM policy (#10728)
* refactor(domain): give strict UTF-8 decoding one owner with an explicit BOM policy * fix(domain): keep the leading-BOM behaviour every migrated UTF-8 decoder had * refactor(domain): read the domain layer's strict UTF-8 through the BOM-policy owner (#10803) Twelve domain decoders built their own fatal TextDecoder with ignoreBOM: true. They now use strictUtf8Decoder("preserve"), which keeps that behaviour: each reads bytes where a leading U+FEFF is content (binary-format names and fields, JSON and XML read byte-for-byte, recorded bodies, registry seeds whose kept bytes are re-emitted). The counted baseline drops from 74 to 62. * refactor(artifacts): read artifact readers' strict UTF-8 through the BOM-policy owner (#10871) Fourteen artifact reader modules (17 sites) built their own fatal TextDecoder. They now take it from strictUtf8Decoder with the policy each had: every one kept a leading BOM (ignoreBOM: true), so they use "preserve"; JavaScriptArtifactFiles keeps it for JavaScript and HTML entries and strips it otherwise, as before. The strict-utf8-decoder baseline drops those 17 sites. * refactor(domain): drop TextDecoder imports left by the strict UTF-8 migration * refactor(application): read MCP registration metadata through the strict UTF-8 owner * refactor(formats): read binary-format readers' strict UTF-8 through the BOM-policy owner (#10903) * refactor(formats): read binary-format readers' strict UTF-8 through the BOM-policy owner * refactor(formats): drop the model readers' unused TextDecoder imports * refactor(browser): read browser capture and fetch strict UTF-8 through the BOM-policy owner (#10935) * refactor(browser): read browser capture and fetch strict UTF-8 through the BOM-policy owner * refactor(native): read LLDB and Mach-O name strict UTF-8 through the BOM-policy owner (#10936) * refactor(native): read LLDB and Mach-O name strict UTF-8 through the BOM-policy owner * refactor(process): read MCP and NDJSON transport frames' strict UTF-8 through the BOM-policy owner (#10937) * refactor(process): read MCP and NDJSON transport frames' strict UTF-8 through the BOM-policy owner * refactor(application): read JSON and file inputs' strict UTF-8 through the BOM-policy owner (#10938) * refactor(application): read JSON and file inputs' strict UTF-8 through the BOM-policy owner * refactor(providers): read IDA, Electron, Ghidra and reference strict UTF-8 through the BOM-policy owner (#10939) * refactor(providers): read IDA, Electron, Ghidra and reference strict UTF-8 through the BOM-policy owner * refactor(evm): read the hex bytecode carrier's strict UTF-8 through the owner and refuse new local decoders (#10940) * refactor(evm): read the hex bytecode carrier's strict UTF-8 through the BOM-policy owner * chore(architecture): match local strict UTF-8 decoders in any option order |
||
|
|
b98fbdc442 |
refactor(ida): let IDA close failures read the session's later close (#10811)
* refactor(errors): read cleanup completion from dependencies instead of pushing it to dependents AnalysisError.cleanupIncomplete becomes a getter over the error's own unresolved state and its bound dependencies. The WeakRef dependents graph and resolveCleanup's push propagation are removed, and subclasses mark their initial state through markCleanupIncomplete instead of overriding a public mutable field. * fix(errors): settle bound dependencies before binding more A composite whose dependencies had released but whose status was never read stayed incomplete when a later dependency was bound. * refactor(errors): let errors read a lease group's release instead of resolving them (#10759) AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink (#10763) * refactor(errors): let errors read a lease group's release instead of resolving them AnalysisCleanupLeaseGroup no longer calls resolveCleanup() on its error. The error holds the group as a release claim and reads cleanupReleased when asked, so completion follows the lease owner without a push. * chore(verify): count resolveCleanup and bindCleanupDependencies calls so they only shrink * refactor(process): let worker cleanup errors read their root epoch's release OwnedWorkerRuntime's root epoch is now an AnalysisCleanupReleaseClaim. Errors bound to it read its release when asked instead of the epoch pushing resolveCleanup() through weak references, and a runtime without a retained root binds an already-released owner. Removes the OwnedWorkerCleanupFailure structural type and four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(pcap): let pcap cleanup errors read command and snapshot release (#10792) Retained pcap commands, retained snapshot failures and snapshot completion descriptors now own their release and errors read it: commands and snapshot failures implement AnalysisCleanupReleaseClaim, and a failed completion-descriptor close is retried through an AnalysisCleanupLease bound to its error. Removes four resolveCleanup() pushes; the counted baseline shrinks accordingly. * refactor(process): let Darwin helper cleanup errors read their owner's release Darwin helper cache and run-token reader root cleanup now record an AnalysisCleanupRelease that every failure reports; a successful retry confirms it. Replaces the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes two resolveCleanup() and two bindCleanupDependencies() calls; both counted baselines shrink. * refactor(ghidra): let Ghidra cleanup errors read the client's and checkpoint's release GhidraClient and GhidraCheckpoint bind each cleanup failure to an AnalysisCleanupRelease and confirm it when a later close or retry releases everything, instead of keeping a set of failures and pushing resolveCleanup() to each. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(process): let debugger session cleanup errors read a confirmed stop OwnedDebuggerSessionRegistry binds each retained gdb or rizin cleanup failure to the session's AnalysisCleanupRelease and confirms it when a stop is confirmed, keeping the latest failure for retry reporting, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(process): drop the debugger registry's unused closeOperation option Returning the latest retained failure removed the last reader of closeOperation; remove the option and the values gdb and rizin supplied. * refactor(server): let environment shutdown errors read a successful close serveEnvironment binds each shutdown failure to an AnalysisCleanupRelease that a later successful close confirms, instead of pushing resolveCleanup() to a set of failures. The state-file retry test now also requires the earlier report to read the release. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(desktop): release retained screen-judge cleanup through its lease Each retained judge or screenshot cleanup owner is wrapped in an AnalysisCleanupLease bound to its failure; close() releases the lease, which records the release the failure reads, instead of closing the owner and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(ida): let IDA close failures read the session's later close IdaSessionClient's close failure binds an owner that is both its resource owner and its release claim, read from the client's closed state, instead of keeping weak references and pushing resolveCleanup() after a successful retry. Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(javascript): let source-map codec cleanup errors read a later close (#10814) * refactor(javascript): let source-map codec cleanup errors read a later close OwnedCodec binds each close failure to an AnalysisCleanupRelease that a later successful close confirms, replacing the first-failure anchor that later failures depended on and the resolveCleanup() push. Removes one resolveCleanup() and one bindCleanupDependencies() call; both counted baselines shrink. * refactor(cutter): let pending Cutter command errors read the completion receipt (#10815) * refactor(cutter): let pending Cutter command errors read the completion receipt Each pending Cutter command keeps an AnalysisCleanupRelease bound to its timeout failure; the producer's terminal completion receipt confirms it instead of pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(application): let provider candidate cleanup errors read the candidate's close (#10817) * refactor(application): let provider candidate cleanup errors read the candidate's close AnalysisProviderRegistry keeps one AnalysisCleanupRelease per candidate whose resource close is unconfirmed; failures bind to it and a later confirmed close confirms it, instead of pushing resolveCleanup() to a set of failures. Removes one resolveCleanup() call; the counted baseline shrinks. * fix(errors): bind a cleanup release claim to an error at most once AnalysisError kept release claims in an array, so a provider whose retried close returned the same error bound the same claim again on every retry and each cleanupIncomplete read scanned the duplicates. Keep the claims in a set. * refactor(application): let reverse-tool cleanup errors read a verified stop (#10819) * refactor(application): let reverse-tool cleanup errors read a verified stop Each retained provider process group in ReverseEngineeringService keeps an AnalysisCleanupRelease; its command and retry failures bind to it and a later verified stop confirms it, instead of collecting failures and pushing resolveCleanup(). Removes one resolveCleanup() call; the counted baseline shrinks. * refactor(sqlite): let SQLite worker and root cleanup errors read their release (#10821) Each retained SQLite snapshot cleanup records an AnalysisCleanupRelease for its worker and for its runtime root; the resource failures bind to them and a verified stop or root removal confirms them, instead of pushing resolveCleanup(). Composite failures keep reading those resource failures. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let JADX and session close failures read their owner's release (#10854) * refactor(android): let JADX cleanup errors read their retained cleanup's release Each retained JADX cleanup records an AnalysisCleanupRelease for the admission failure's descriptor owners and one for the whole retained cleanup. The admission failure and every error the cleanup reports bind to them, and a confirmed close confirms them, instead of pushing resolveCleanup() through WeakRefs to reported errors. Removes two resolveCleanup() calls; the counted baseline shrinks. * refactor(application): let session close failures read the client's later close A retained session cleanup records an AnalysisCleanupRelease; unowned cleanup failures the client's close reported bind to it and the successful close confirms it, instead of the session collecting them and pushing resolveCleanup(). Failures that already follow their own owner keep reading it. Adds a regression for an unowned close failure. Removes one resolveCleanup() call; the counted baseline shrinks. |
||
|
|
5d1a47768a |
feat(artifacts): surface the named integrity check in public artifact errors (#11052)
* feat(artifacts): surface the named integrity check in public artifact errors ArtifactOperationError now carries integrityCheck from the reader failure and projects it as details.integrity_check, including with artifact integrity details. Rebuild sites copied a different subset of reader facts each (ProcessCli.artifactFailureFacts, withCleanup, desktop, file-operation cleanup, resource export, DMG inventory, safe output tree); they now spread ArtifactReaderFailure.primaryFacts(), so a new reader fact has one owner. ArtifactIntegrityCheck moves to the domain beside ArtifactAdmissionLimit. * test(artifacts): check rebuilt cleanup failures keep the named integrity check |
||
|
|
9be6a96fd6 |
refactor(cli): project reconstruction and source-to-bundle documents from their contracts (#10697)
* refactor(cli): project reconstruction ledger and coverage commands from their contracts * refactor(cli): project compare-source-to-bundle from its contract and refuse omitted document fields * fix(cli): advertise caller paths in JSON documents as the CLI admits them * fix(cli): advertise that JSON document caller paths exclude URLs * refactor(cli): narrow omitted document field refusal to object documents * test(cli): give the coverage document fixture the current evidence_format |
||
|
|
fd2eabb12a |
feat(setup): manage fx, Junie, Goose and Kilo registrations through the client table (#10709)
* feat(setup): manage fx registrations with its private profile modes fx becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers fx when ~/.fx or FX_HOME exists. Setup now publishes a private profile through the same owner as mcp add (folder 0700, file 0600) and repairs those modes when the row is otherwise current. Doctor parses fx's array launcher instead of reporting it invalid. * fix(setup): judge fx's private profile by its targets and keep its cleanup owner Address review: privateProfileModesCurrent reads the modes of the canonical file and folder, so a linked profile becomes current; clientConfigurationAligned applies the same modes rule as plan and apply; a private-folder close failure reaches the caller with its cleanup owner instead of becoming a write failure; and the setup plan names the folder and file modes it sets. * fix(setup): keep fx's recovery backups owner-only beside a linked profile Setup and uninstall copied a private profile's original bytes with copyFile, so a backup beside a linked ~/.fx/mcp.json kept the target's readable mode outside the folder setup secures. Both now use the owner-only backup owner that mcp add already used. * feat(setup): manage Junie registrations and apply its location policy (#10712) * feat(setup): manage Junie registrations and apply its location policy Junie becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers Junie when its home exists. Whether Junie loads its default user MCP file now has one owner, read through the client policy block that setup, doctor and mcp add already consult: setup and mcp add refuse, and doctor reports, a registration Junie would not load. * fix(setup): read Junie's user configuration as strict JSON Address review: Junie loads config.json as strict JSON, so comments, trailing commas or an empty file leave its MCP location choice unknown, as before the move into the row. Filesystem tests also clear JUNIE_*, FX_HOME and MCPORTER_CONFIG so a developer's own client locations cannot be inspected or removed. * test(setup): keep the detected client order out of the lifecycle suite body The expected detection order grew with each folded client until the suite callback exceeded the max-lines-per-function lint limit. * fix(update): report a client whose policy setup refuses instead of failing maintenance Junie's disabled default locations (and Gemini's settings policy) make doctor report the registration stale, but setup refuses that client, so selecting it failed every other client's maintenance. The registration inspection now carries the setup blocker, and maintenance lists that client with its reason instead of selecting it. * refactor(setup): read fx's private-profile host through HOST_PLATFORM The fx private-profile mode checks and permissions describe the host REA runs on, so they take it from the host-platform owner instead of reading process.platform (refused by the ratchet from #10911). * feat(setup): manage Goose registrations across its configuration layers (#10715) * feat(setup): manage Goose registrations across its configuration layers Goose becomes a client-table row, so doctor, update and uninstall see the registration rea mcp add wrote, and setup offers Goose when its user file or system file exists. Goose loads its system file and GOOSE_ADDITIONAL_CONFIG_FILES beneath the user file and overlays each extension one field deep; doctor now reports that effective registration, while setup, update and uninstall change only the user file. Doctor also parses Goose's cmd launcher instead of reporting it invalid. * fix(setup): keep Goose's layered environment and load order through setup and uninstall Address review: read Goose's env alias and apply requested settings over envs; keep an inherited lower envs map instead of masking it with an empty default; keep each layer's last load so a repeated user file keeps its precedence; split GOOSE_ADDITIONAL_CONFIG_FILES with Windows quoting; validate only the effective environment across read-only layers; refuse uninstall while a read-only layer keeps REA enabled; and clear Goose's location variables in tests. * fix(setup): apply requested Goose settings over the inherited environment * fix(setup): leave lower-layer Goose settings in force and read admin layers read-only Setup no longer writes its default timeout, enabled, name or description into Goose's user entry when only a lower layer declares that setting, so the inherited value keeps applying and a repeat setup stays current. Uninstall reads Goose's read-only lower layers where Goose reads them, without the write target's ownership check, so an administrator-owned system file no longer blocks removal. The client table accepts an injected Goose system-config path so tests no longer read or skip on the host's /etc/goose/config.yaml; adds a shadowed-invalid-lower-layer regression. * fix(setup): keep an inherited Goose env alias's spelling when writing the user entry Goose overlays each extension field separately, so writing envs into the user file beside a lower layer's env alias left both in force, which readers reject as ambiguous. Setup now writes the user map under the alias a lower layer declares, and mcp add neither adds a default envs map beside an inherited alias nor renames a user alias the lower layer shares. * test(setup): inject Goose's system layer into mcp add selection resolveMcpRegistrationClients accepts the caller's system configuration paths, so the Goose layers test no longer reads the host's /etc/goose/config.yaml. * fix(setup): report REA's Goose registration that only a read-only layer defines * test(setup): pass an isolated Goose system path through update maintenance and the mcp add table * fix(setup): judge Goose uninstall by the merged entry and stop on an unreadable lower layer * fix(setup): select Goose's env alias by presence so a null alias stays malformed * fix(setup): use the shared record predicate for Goose's layered merge after #10588 * feat(setup): give Kilo a client-table row with an async layered location (#10823) * feat(setup): give Kilo a client-table row with an async layered location The client table gains a layeredLocation hook and resolveSupportedClients, which awaits it. Kilo's row resolves its user-scope layers through the same owner rea mcp add uses (KiloClientLocation), so both pick the same write target; the synchronous row keeps kilo.json in Kilo's config root with every candidate layer. The table refuses a relative KILO_CONFIG, KILO_CONFIG_DIR or XDG_CONFIG_HOME because Kilo's working directory is unknown. Refs #7181 * fix(setup): treat every folder Kilo reads as evidence that it is installed * fix(setup): normalize Kilo's absolute table paths and parse its command array * feat(setup): resolve the client table's layered locations in setup, doctor, update and uninstall (#10832) SetupHost (detection and the selectable table), ClientRegistrationStatus, uninstall, doctor's selected-registration environment and the mcp add catalog now read resolveSupportedClients, so each sees the Kilo layer Kilo writes rather than the synchronous default. Refs #7181 * docs(adr): record the one-client-table decision for setup and mcp add * fix(setup): refuse to read a client row whose location is unresolved Doctor's selected-client settings read a Kilo row whose relative KILO_CONFIG left only path evidence, so it inspected a file relative to REA's folder. The shared configuration reader now refuses such a row, so every reader reports the registration as unreadable. * docs(adr): name the row's layeredLocation hook * feat(setup): read KILO_CONFIG_CONTENT as Kilo's top read-only layer (#10851) * feat(setup): read KILO_CONFIG_CONTENT as Kilo's top read-only layer * fix(setup): refuse a Kilo uninstall that would expose or keep another layer's rea entry (#10852) * fix(setup): recheck KILO_CONFIG_CONTENT at write time and name it in doctor's recovery * refactor(mcp): register Kilo through its table row and remove the registration-only catalog kind (#10862) * refactor(mcp): register Kilo through its table row and remove the registration-only catalog kind * refactor(mcp): resolve user-scope targets in the catalog so location modules never import the client table * test(setup): cover Kilo's KILO_CONFIG, home-folder and inline-only layers * fix(setup): report REA's Kilo entry that only KILO_CONFIG_CONTENT sets during uninstall Doctor reports a registration that KILO_CONFIG_CONTENT alone defines, but uninstall found no file entry and reported Kilo as skipped. Uninstall now reports it once as failed and names the variable to edit. * docs(adr): record Kilo's inline layer in the client-table decision * fix(setup): compare Windows environment names without case when a higher layer overrides REA's entry Kilo's inline-layer check and Gemini's system-override check compared environment maps by exact key, so an equal Path beside PATH on Windows was reported as an override and setup refused the client. Both compare the entry as the client launches it. * fix(update): leave a stale Kilo registration KILO_CONFIG_CONTENT sets out of maintenance Setup refuses a refresh the inline layer would override, and one refused client failed every other client's maintenance. The registration inspection now names the inline layer as the setup blocker of a stale entry, and maintenance reports Kilo with that recovery instead of selecting it. * fix(setup): refuse relative JUNIE_HOME and Cline CLI overrides like the other client roots (#10909) * fix(setup): refuse relative JUNIE_HOME and Cline CLI overrides like the other client roots * fix(setup): refuse Windows client paths without a drive that follow the client's current drive * fix(update): select maintenance clients through setup's own refresh refusal check Maintenance predicted setup's refusal with its own rule: any inline rea entry blocked a stale registration, while an aligned one was never checked. A harmless KILO_CONFIG_CONTENT entry (enabled: true) kept a stale Kilo launcher pinned, and an inline value setup would not write (an extra environment variable) let an aligned Kilo registration block every client's maintenance. Setup's refusal checks (client policy, then the inline override comparison of the entry it would write) now live in one reader that setup's alignment check and maintenance share. Maintenance asks it for every owned enabled candidate and reports a refused client with setup's remediation and its real state. * fix(update): keep failed refresh-check reads owned by the supplied maintenance scope clientRefreshRefusal read the client's layers, target file and policy without the caller's resource scope, so a close that failed during those reads threw a cleanup failure no scope retained; maintenance then reported it as text and the scope's close could not retry the descriptor. The refresh reader now takes the scope and passes it to every read. * fix(setup): take the Kilo layer readers' default host from HOST_PLATFORM and the shared record predicate After rebasing on main (#10911, #10588): the new inlineRegistrationOverride and resolveSupportedClients defaults read the running host through the host-platform owner, and the layered launcher merge uses isRecord. * fix(update): keep an unreadable layer's reason in the refresh refusal check readClientRefresh returned undefined for an unreadable or malformed layer, so clientRefreshRefusal reported no refusal and maintenance selected a client whose setup preflight then failed. The reader returns the typed file failure, and the refusal check reports its detail like setup's preflight does. * fix(setup): count REA's entry in KILO_CONFIG_CONTENT as Kilo lifecycle evidence Doctor, update and uninstall inspected a client only when one of its folders existed, so a registration set only by KILO_CONFIG_CONTENT was skipped. A read-only inline layer that sets REA's entry is now evidence on its own. * fix(update): report a client whose only conflict is a discovered provider path as needing setup * fix(update): match discovered settings by the platform's environment identity * fix(update): preflight maintenance with setup's write-target checks and treat discovered inline paths as unknown |
||
|
|
15de1d4dce |
feat(evidence)!: require JavaScript, browser, managed and reference-source facts their producers always write (#10990)
* feat(javascript)!: require the runtime parse-failure count and active Electron execution paths The V8 Inspector projection always writes scripts.parse_failed_total and the active Electron service always commits parameters.resolved_paths, so both are now required. Runtime reconciliation reads the admitted execution paths only and no longer falls back to request-spelled paths in parameters, and checks the observed executable path against them on every capture. JavaScriptStaticAnalysis.routes and module_runtime keep their omission, which current producers still make (a checkpoint that cannot retain route facts; no recovered factory runtime); their comments now say so instead of naming historical analyses. BREAKING CHANGE: JavaScript runtime observations without scripts.parse_failed_total, and active Electron Evidence without parameters.resolved_paths, are refused as malformed; recreate the observation. * test(javascript): give the shared Node reconciliation fixture the required parse-failure count * feat(browser)!: require browser observation facts their producers always write (#10991) * feat(browser)!: require browser observation facts their producers always write The source-map fetcher always writes effective_url (string or null), the web bundle analyzer always writes schema_property_names_coverage, and the CDP storage fingerprinter always marks IndexedDB schema fingerprints with projection_version 2. Each is now required. The IndexedDB marker is tied to its scope by a discriminated union and derived from the scope in the producer, so compare_web_captures no longer carries the store-only projection branch. response_identity and the WebMCP consequential hint keep their omission, which current producers still make (a body not fully read; an invalid annotation); the guide no longer attributes it to historical captures. BREAKING CHANGE: source-map items without effective_url, WebMCP declarations without schema_property_names_coverage, and IndexedDB schema fingerprints without projection_version are refused as malformed; recreate the capture. * feat(managed)!: refuse members beside a null signature resolution (#10992) * feat(managed)!: refuse members beside a null signature resolution signature_resolution is null only when member decoding exceeded capacity, and the capacity-recovery producer then examines no members. The managed member inspection schema now enforces that: a null resolution with any field, method, member reference, call edge or field access is malformed. With that rule, every admitted inspection with members attests type-name resolution, so the raw-digest fallback is unreachable and is deleted: comparableSides, hasSignatureResolution, the comparison's signatureResolutionExamined flag and the "does not attest" limitation. The shared workflow example that carried resolved digests beside a null attestation now attests resolution. BREAKING CHANGE: managed member Evidence with a null signature_resolution and any examined member is refused as malformed; recreate the observation. * docs: describe historical Evidence by what the format revision now refuses (#10993) SQLite worker_timeout_ms is required, so the SQLite guide no longer reads a missing value as unknown settings. The IL2CPP, ESP image and process capture guides now say that bundles exported without evidence_format are refused, while a standalone record from an earlier release is still read with the stated omission semantics (records carry no format marker yet). The route inventory guide describes a parent without route_inventory by its meaning rather than by its age. * refactor(javascript): require static analysis coverage from the JavaScript worker (#11001) * refactor(javascript): require static analysis coverage from the JavaScript worker Both JavaScript static producers always write analysis_coverage: the analyzer measures it on every parsed source and the failed-parse result carries an unexamined coverage. The worker schema and the static analysis type therefore require it, the preload-discovery checkpoint copies it unconditionally, and ElectronBoundaryAnalysis reads Electron applicability and examination limits from it alone. The fallback that re-derived Electron use from semantic module links and retained references for analyses without coverage is deleted, as are the graph and builder branches for a missing coverage. Retained Evidence graph observations are unchanged: the analysis view still counts a stored JavaScript observation without analysis_coverage as unmeasured, since standalone records carry no format marker yet. The worker runs from the same build as its parent, so no external caller sees the stricter reply schema. * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts (#11002) * feat(browser)!: require storage fingerprint, Link context, mapping index and invalid-map identity facts Each field is written by its only producer on every capture: - The CDP storage capture always writes content_fingerprints, fingerprint_algorithm and fingerprints_complete, so their schema defaults are removed. - The CDP Link header projection always writes context_url and context_scope, so they are required. - The source-map fetcher writes source_index and declaration_index on every mapping row, so they are required. - The fetcher judges a map invalid only after reading its complete body. A separate invalidSourceMapItem builder now takes the response identity as a required argument, and the schema's invalid member requires response_identity; fetch_failed keeps it optional because those rows can come from a body that was not fully read. The browser and source-location guides no longer describe these fields as optional for older saved captures. BREAKING CHANGE: page inspections without the storage fingerprint fields or Link context fields, source-map mapping rows without their indexes, and invalid source-map items without response_identity are refused as malformed; recreate the capture. * test(browser): keep source-omission coverage on a still-defaulted field and refuse a missing fingerprint algorithm * feat(browser)!: require web-bundle target origin, inspection producer facts, scenario redirect state and exclusion kind (#11014) feat(browser)!: require web-bundle target origin, page inspection producer facts, scenario redirect state and exclusion kind Each field is written by its only producer on every record: - buildCaptureObservation always writes capture.target_origin (the validated origin or null), so analyze_web_bundle Evidence and both web-bundle view results require it; the view's conditional spread is gone. - The CDP page capture always writes accessibility node states, script frame_id (null when unattributed) and worker opener_target_id and parent_frame_id, so their schema defaults are removed. - PlaywrightScenarioNetwork writes redirected_from_transaction_state exactly when the predecessor ID is null, so request events now require it there and still refuse it on linked events. - The reference-source importer writes entry_kind on every exclusion (unknown when the kind was not observed), so it is required. The browser scenario contract and CLI guide no longer describe older captures or exclusions without these fields. BREAKING CHANGE: web-bundle analyses without capture.target_origin, page inspections without these script, accessibility or worker fields, scenario network events with a null predecessor and no redirect state, and reference source graphs whose exclusions lack entry_kind are refused as malformed; recreate the capture or re-import the source. |
||
|
|
a6cbe8b12a |
feat(providers): bound runOwned work and close by one deadline (#10996)
* feat(providers): bound runOwned work and close by one deadline * fix(providers): read an expired budget at settle time and keep a caller abort during cleanup * fix(providers): follow a late close rejection's owner and keep captured output through budget replacements * fix(providers): track budget expiry apart from the caller, keep replaced work's cleanup, treat empty leases as none * fix(providers): classify thrown abort reasons, keep recorded failures and follow a late close owner's resources Work that throws its signal's abort reason (throwIfAborted) is now a cancellation, so an elapsed budget becomes a timeout and a caller abort stays a cancellation. A budget cancellation replaced by a timeout or a caller cancellation keeps the secondary failures it recorded. A late close rejection that names its own owner now also supplies the retained failure's resources. * fix(providers): classify only the budget's own abort reason, and follow only a late rejection that reports its own cleanup A caller's abort reason is opaque, so a thrown value equal to it stays the work's failure with the caller's cancellation retained; only the budget's typed OwnerCancellation.deadlineElapsed marks a thrown abort as the budget's. A late close rejection without unreleased cleanup of its own (such as a cancellation) no longer confirms release or replaces the fallback resource. * fix(providers): follow a late close owner that already released, by cleanup ownership not completion AnalysisError.carriesCleanup owns whether an error ever owned cleanup, apart from whether it finished. runOwned's late close rejection uses it, so a producer error released by a concurrent retry still confirms release, while a cancellation without cleanup keeps the close's lease pending. Uninstall and SetupCleanupOwner used the same four-clause predicate locally; they now read the owner. |
||
|
|
63b0426e40 |
fix(errors): rethrow internal invariant violations from plist consumers and the native output projection (#11029)
* fix(plist): rethrow internal invariant violations from plist consumers KeyedArchiveReader reported any non-limit decode failure as a format failure, InterfaceBuilderAnalysis listed it as an invalid archive, ReleaseExposureReader fell back to scanning raw bytes, and the native plist parser reported it as provider output. An InternalInvariantError is a REA defect, not evidence about the input, so each consumer now rethrows it. The native parser's binary path now shares its one cause projection instead of a duplicate. * fix(native): rethrow internal invariant violations from the native output projection nativeOutputFailure wrapped any producer failure as AnalysisOutputError, so a REA defect thrown while reading a plist or dispatching a command was reported as native output parsing. It now rethrows InternalInvariantError, which reaches the provider's adapter-failure path with the invariant as its cause. * fix(artifacts): rethrow internal invariant violations from the shared artifact failure mapper translateArtifactFailure turned every unrecognised cause into an ArtifactOperationError with reason io, so the keyed-archive and Interface Builder rethrows still reached users as artifact read failures. The shared mapper now rethrows InternalInvariantError, and the deferred client reports it as a ProviderAdapterError. Provider-level tests drive both operations through that client. * refactor(dotnet): report managed reader defects through invariantViolation (#11030) * refactor(dotnet): report managed reader defects through invariantViolation The managed readers threw plain TypeError and RangeError for states their callers rule out: an allowance or method page outside the input schema, a missing snapshot after identity admission, and a missing CLI header after the caller already returned for it. These are REA defects, not malformed targets, so they throw invariantViolation. The two CLI re-checks are gone: the callers pass the CLI header they already narrowed. The dotnet parser-plain-throw baseline drops from 6 to 0. * refactor(providers): refuse unusable tool paths and record marker mismatches without throwing to their own catch (#11031) * refactor(firmware): refuse unusable tool paths without throwing to its own catch resolveFirmwareCommand threw a plain TypeError for a configured engine or limiter path that is not a regular file, only to catch it in the next line and wrap it as an unavailable capability. A helper now returns why a path cannot run, and each caller builds the one refusal directly. Refusal reasons are unchanged; the directory tests now pin them exactly. The firmware parser-plain-throw baseline drops from 2 to 0. * refactor(pwndbg): refuse unusable debugger paths without throwing to its own catch inspectPwndbgCore threw plain Errors for a relative or wrong-kind configured path only to catch them and wrap them as an unavailable capability. A helper now returns why a path cannot be used, with any host error as its cause, and the loop builds the one refusal. Cancellation between host checks still propagates. Refusal reasons are unchanged. The PwndbgCoreContext parser-plain-throw baseline entry is removed. * refactor(pwntools): record a mismatched failure marker without throwing to its own catch readPwntoolsFailureEvidence threw a plain Error when the private bridge marker disagreed with the exit status, only to catch it and record its message as the marker failure. The mismatch is now recorded directly. The recorded evidence is unchanged; a unit test pins both the matching and the mismatched marker. The PwntoolsResourceLimits parser-plain-throw baseline entry is removed. * fix(android): report an unobserved Java probe as a REA defect, not a Java refusal (#11032) * fix(android): report an unobserved Java probe as a REA defect, not a Java refusal When runOwnedCommand resolved without observing the completed run, the probe threw a plain Error that its catch then classified as a Java runtime refusal, telling the caller to review their launcher. The state is a broken internal assumption, so the probe throws invariantViolation and projects it as a jadx adapter failure. The JadxJavaProbe parser-plain-throw baseline entry is removed. * refactor(native): report native provider defects through invariantViolation (#11033) * refactor(native): report native provider defects through invariantViolation Native providers threw plain Error and TypeError for states their own earlier steps rule out: a client with no target, a measured slice with no selection, a read longer than requested, a decoder command without its runtime, an LLDB root released before its children, and an IPS integer fact from another reader. These are REA defects, so they throw invariantViolation. NativeUiInterruptionControl no longer needs a throw: recording the deadline interruption returns the interruption its error is built from. Six native parser-plain-throw baseline entries drop. * refactor(native): report malformed lipo, swift-demangle and UI helper output through ParseFailure (#11034) * refactor(native): report malformed lipo and swift-demangle output through ParseFailure The lipo and swift-demangle output parsers threw plain TypeError for output that breaks their framing, and the lipo result classifier caught every TypeError as malformed output, so a host TypeError from a REA defect was reported as lipo output. Both parsers now throw malformedInput with their own format, and the lipo classifier accepts ParseFailureError instead of TypeError. Messages and the consumers' output and format failure categories are unchanged. Four native parser-plain-throw baseline entries drop. * refactor(native): report the UI helper's non-JSON output through ParseFailure The native UI helper runtime threw a plain Error when the helper's stdout was not JSON. It now throws malformedInput with its own format and the JSON failure as cause. The observation boundary still reports it as a native-macos adapter failure with the same reason. The NativeUiHelperRuntime parser-plain-throw baseline entry is removed. * refactor(verify): keep process-lifecycle owners out of the parser plain-throw guard (#11035) * refactor(verify): keep process-lifecycle owners out of the parser plain-throw guard JadxWorkspaceRoot and PwntoolsDecoder sit in parser folders but own a private helper process; their remaining plain throws report the helper's startup, handshake and cleanup outcomes, not parse faults. The guard now names them as process-lifecycle owners and leaves them out, so their five baseline entries drop without inventing parse errors for process failures. * refactor(parsers): report the remaining artifact, il2cpp, model and domain defects through invariantViolation (#11036) * refactor(parsers): report the remaining artifact, il2cpp, model and domain defects through invariantViolation Nine plain Error, TypeError and RangeError throws in parser folders reported broken internal assumptions or caller contracts (an uninitialized ZIP or DMG reader, a missing scan result, a non-byte stream chunk, an invalid traversal or marshal limit, a header count or linking fact the reader itself should have produced, a misordered Safetensors budget, an append after fingerprinting). None is an input fault, and no catch site depends on their class. They now throw invariantViolation with the same messages, and their parser-plain-throw baseline entries drop. * refactor(evidence): refuse an earlier Evidence format through ParseFailure (#11037) * refactor(evidence): refuse an earlier Evidence format through ParseFailure UnsupportedEvidenceFormatError restated the ParseFailure algebra as its own TypeError subclass. The format owner now throws unsupportedInput for the evidence-bundle format at the evidence_format field and exports the predicate its consumers use. The bundle reader's unsupported-format kind and message are unchanged. The snapshot reader surfaced only TypeError messages, so it now also surfaces the format refusal and keeps its recreate guidance; a boundary test pins that. * refactor(native): report Mach-O reader and inspection defects through invariantViolation (#11042) The Mach-O inspection plan reads the lipo, nm and dyld_info captures it just ran, the dispatch metadata reader is called only for Mach-O executables, and the command-name reader takes limits its callers derive. A missing capture, a non-Mach-O target or a malformed limit is a REA defect, not an input fault, so these six sites throw invariantViolation with their existing messages instead of TypeError. No catch site depends on their class. Their parser-plain-throw baseline entries drop. * fix(artifacts): join the Interface Builder cleanup failure to a catalog defect When catalog work failed while the concurrent Interface Builder reader failed to close, analyzeAppleAssetCatalogs built the primary through translateArtifactFailure before joining cleanup. That mapper now rethrows an InternalInvariantError, so a defect skipped the join and the reader's retained resources were lost. The defect now becomes the artifact graph provider's adapter failure at that site and joins the cleanup failure as before. |
||
|
|
0d86953c32 |
feat(evidence): name a standalone Evidence record with detected_kind on every bundle refusal (#11039)
The file reader, inline bundle reader and investigation ledger refused a single Evidence record with only a message saying so. The file reader's wrong-kind failure now carries detected_kind "evidence-record" (as it already did for analysis snapshots), and the inline and ledger refusals carry it on their input issue through one domain helper. Tests assert the field instead of the sentence. The inline CLI/MCP case now asserts full parity: since compact input schemas, MCP reaches the same domain reader. |
||
|
|
423489a761 |
feat(evidence): name the side and issue path of comparison source integrity failures (#11049)
* feat(process): name the side and issue path of process-capture integrity failures compare_process_captures reported which side failed validation, and where, only in the message. EvidenceIntegrityError now carries an optional side and issue path, projected as details.side and details.issue_path, and the CLI's malformed-capture issue carries observed.issue_path. The first issue path comes from the same selection describeValidationFailure names. * feat(evidence): report source authentication issue paths from the Evidence owner readEvidence and readImmutableEvidence now set the record-relative issue path on their integrity failure, and readEvidencePayload sets it when the caller says where the payload sits. compare_functions passes its side, so a tampered function source reports details.side and details.issue_path like compare_process_captures. Process capture result issue paths are now relative to the Evidence record (normalized_result.*) on both adapters. |
||
|
|
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 |
||
|
|
2826592759 |
refactor(application): build application cancellations with a required reason (#10574)
* refactor(application): build application cancellations with a required reason Migrate every AnalysisCancelledError construction under src/application to cancelledBy and lower the guard baseline from 671 to 442. Shutdown refusals in BinarySession report OwnerCancellation.ownerClosed when the caller did not abort, instead of an undefined reason. ReverseEngineeringService and DesktopBuildOwnedWork close their work with the typed owner reason. SharedStartupAttempt returns the departing caller's reason with a cancelled wait. One shared isAborted predicate replaces eleven local copies and narrows a checked signal for cancelledBy. * refactor(desktop): drop an unused cancellation import from desktop capture state |
||
|
|
54230c2e7b |
refactor(setup): require the platform for skill destinations instead of reading the host (#11006)
* refactor(setup): require the platform for skill destinations instead of reading the host The setup skill owner defaulted seven entry points to process.platform. Every production caller (setup host, doctor, uninstall, update maintenance) already passes the platform it was composed with, so the defaults only let a caller silently mix the host REA runs on with the one it asked about. The platform is now a required parameter; tests name the platform they exercise, the setup fixture passes its declared host, and the ambient-read baseline drops SetupSkill.ts (7 to 0). * test(setup): expect the fake host's POSIX skill paths in planning tests |
||
|
|
f46cd6770c | test: advance the Rizin and build computer fixed waits instead of sleeping through them (#11026) | ||
|
|
5cfaac0834 | refactor(process): require the platform for environment snapshots instead of reading the host (#11028) | ||
|
|
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. |
||
|
|
536c54ca1f | feat(process): name whether a process input file failed to read or to parse (#11008) | ||
|
|
e0249db65c | feat(evidence): mark a snapshot supplied to import_evidence_bundle with detected_kind (#11010) | ||
|
|
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 |
||
|
|
5775c8124f | test(desktop): inject the build computer's drawn-screenshot wait so its MCP test runs in 2 s (#10999) | ||
|
|
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 |
||
|
|
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 |
||
|
|
b655645608 |
refactor(errors): give caller aborts a typed reason at the adapters (#10633)
* refactor(errors): give caller aborts a typed reason at the adapters Squashes 908813551f, 87858de4dc (fix(mcp): preserve cancellation reasons in handlers) and fa151dc3f6 (test(server): race handler-entry gates against the triggering tool call) onto main without #10566's pre-squash commits. * refactor(errors): give owner-initiated aborts a typed reason outside the browser adapters (#10692) * refactor(errors): give owner-initiated aborts a typed reason outside the browser adapters * refactor(verify): keep the abort-reason scan receiver-independent Playwright's route.abort takes a network error code; the one call site now names its default code instead of the guard exempting a variable name. * refactor(browser): give owner-initiated CDP aborts typed reasons (#10706) * refactor(browser): give owner-initiated CDP aborts typed reasons * fix(browser): give the page-side request fetch page-native abort reasons The request callback runs in the page through page.evaluate and cannot reach REA's modules. Define its deadline and cleanup reasons as DOMExceptions inside the callback, and make the test fake evaluate the callback from its source so module imports are unavailable, as in a page. * test(process): expect the reader close's typed owner reason Closing the Darwin run-token reader aborts its compilation with OwnerCancellation.ownerClosed since the owner-abort change in this PR; the boundary test still expected the default DOMException. * fix(server): report HTTP session replacement and shutdown to pending tools as an owner close |
||
|
|
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. |
||
|
|
85df21992f |
refactor(native): read retained inventory views through the operation fact contracts (#10883)
* refactor(native): read retained inventory views through the operation fact contracts * refactor(native): read matching inventories through the operation fact contracts (#10887) * refactor(native): read dispatch symbol fallbacks as lenient name facts at the port (#10889) * refactor(native): read dispatch symbol fallbacks as lenient name facts at the port * test(native): accept undeclared name-row fields in both dispatch consumers * refactor(native): read literal searches and overview counts as operation facts (#10894) * refactor(native): read literal searches and overview counts as operation facts * refactor(native): read addressed inventory rows as operation facts in every reader (#10899) * refactor(native): read addressed inventory rows as operation facts in every reader * test(native): cover xrefs name resolution through the name fact contract * test(server): pin procedure completion to the procedure inventory contract |
||
|
|
5bf66f7500 |
refactor(domain): one owner for the non-array record predicate (#10588)
* refactor(domain): one owner for the non-array record predicate Thirty-four source files each declared isRecord as a non-null object that is not an array, and six more spelled the same predicate as isObject, isSchemaRecord or isStorageRecord. They now import isRecord from src/domain/isRecord.ts, whose overloads keep JsonValue narrowing for the desktop and environment readers. DshCordisPatch's predicate also excludes Cordis expressions, so it is renamed isPatchRecord. architecture-guards refuses a new local copy under any name. The seven files that still hold one are listed and must leave the list when their copy goes. * fix(guards): count record predicate copies precisely * test(hopper): retry after confirmed application exit * fix: reject stale record predicate exceptions |
||
|
|
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 |
||
|
|
66d1527a3d | refactor(native): parse native inventory results once at the operation port (#10880) | ||
|
|
8443930bd3 |
refactor(limits): declare the Node timer bound and duration schema once (#10640)
* refactor(limits): declare the Node timer bound and duration schema once Fifteen modules re-declared 2_147_483_647 as their own timer maximum and eleven built the same 1..2^31-1 millisecond schema. They now use MAX_NODE_TIMER_DELAY_MS and timerDurationMsSchema from src/domain/analysisResourceLimits.ts, and an architecture guard rejects the literal outside that owner and five non-timer int32 bounds. The generated MCP tool catalog is byte-identical. * refactor(limits): keep the JVM processor-count bound separate from the timer bound REA_JADX_ACTIVE_PROCESSOR_COUNT is a Java int count, not a timer delay, so it keeps its own named bound and a documented exception in the signed 32-bit guard. Remove the timer-bound and zod imports the duration-schema migration left unused. * refactor(limits): keep the TShark packet-count bound separate from the timer bound packet_limit is passed to TShark's -c as a C int packet count, not a timer delay, so it keeps its own named bound and a documented exception in the signed 32-bit guard. |
||
|
|
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. |
||
|
|
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. |