Commit Graph

4302 Commits

Author SHA1 Message Date
morluto 0d596fa8f7 docs(limits): describe how to design admission recovery (#6368)
* fix(reconstruction): dedupe residual unknown ids with uniqueSorted

Merged obligation candidates called uniqueBy, which is not defined, so
the project did not typecheck. String ids already use uniqueSorted.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* docs(limits): describe how to design admission recovery

Add a short contributor guide for named defaults, settings, recovery
text, and the agent recovery ladder, and mirror that ladder into the
authored skill.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(hopper): pass distribution readers into install-host tests

systemLinuxHopperInstallHost now requires the caller's distribution
reader. The Linux install tests still passed only the environment, so
typecheck failed.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* docs(limits): name the parser doctor shares with startup

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: align pcap, storage, and regex fixtures with current contracts

Source and portable CI failed on fixtures that still described the
previous pcap client identity, legacy storage fingerprints, and the
old regex deadline sentence.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* docs: link repository experiments outside the built site

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 05:10:36 +08:00
abdulwasea89 42e1a17d6e fix(setup): preserve concurrent client configuration edits (#4855)
* fix(setup): preserve concurrent client configuration edits

* fix(setup): normalize configuration transaction queue paths

* fix(setup): report concurrent snapshot read conflicts

* test(setup): isolate Pi workflows from installed Hopper

* test: align inherited fixtures with current analysis contracts

* test(ida): assert search recovery instead of diagnostic prose

* fix(setup): share configuration queue keys across directory aliases

Resolve parent-directory aliases for regular and missing configuration
paths so a directory symlink and its real directory serialize setup
instead of racing the same file.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 05:06:13 +08:00
morluto 3afec59523 test(process): publish compiler readiness atomically and verify native identity
Prevent polling readers from observing truncated readiness JSON in compiler fixtures. Retain deterministic cancellation controls and strengthen the real Swift compiler case to run native identity inspection, verify parent/group facts, and check stable identity across reads.

Validated all 32 Darwin tests with the real host toolchain. A delayed write reproduces the old JSON race; delayed atomic publication passes. No CI timeout or retry changes.
2026-10-23 05:03:15 +08:00
morluto bea6b98e84 test: prefer structured assertions over recovery prose (#6379)
* test: prefer structured assertions over recovery prose

Lock regex, IDA, Hopper/Kuna, MCP budget, capture-heap, and pcap
failures on error codes and reported limits instead of full recovery
sentences.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: keep decoder heap negatives off the Windows reserve

"512 MiB" also appears in the Bun Windows reserve sentence. The
negative check stays on "512 MiB (source setting)", which is the other
adapter's heap.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: keep the one-retry cap and deadline recovery tokens

The lost-connection guidance must say once only, so an unlimited
"whenever it is safe" rewrite fails. Deadline recovery still has to
name set, restart, the floor, and the maximum constant.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: keep heap, MCP, pcap, and preload recovery tokens

Codex still wanted the set/restart/floor/maximum heap guidance, MCP
default/floor/maximum bounds, Wireshark install guidance, and the
dropped-preload attribution limit as separate tokens.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: keep shared-context and transport recovery tokens

Shared-context capture must still exclude requests without a known root
or descendant frame. Shutdown must end the REA process before starting
again, and a failed HTTP listen must offer another port or stopping the
process that holds it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: keep handoff, input-check, and budget format tokens

Skill and server guidance must still tell the user to restart the MCP
client. Process failures must still say to check the input files. Invalid
MCP phase budgets must still say positive decimal integer and ms.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: bind budget floors and active deadline sources

The phase-budget minimum is the start of "from N to M ms", so a digit
inside the maximum no longer satisfies it. Capability text must contain
the active "N ms (source ...)" pair, not the default number and a heap
source mentioned apart.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: bind heap MiB sources and pcap host tokens

A configured 256 MiB request must appear as "256 MiB (source setting)",
so a byte-sized 256 no longer passes. Unsupported pcap hosts must still
name Linux, util-linux, Windows, and owned Job Objects as separate tokens.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: bind the selected decoder heap to MiB and source

The two-adapter limitation must contain "256 MiB (source setting)".
The exhaustion message binds that capacity as "256 MiB V8 old-generation
heap (source setting)", so a byte-sized 256 no longer passes.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: bind doctor client seconds and prlimit absolute guidance

Doctor recovery must name startup_timeout_sec of the policy's seconds,
so a hardcoded 60 no longer passes while the policy stays 30. A relative
prlimit must say the value must be absolute and tell the user to check
REA_TSHARK_PRLIMIT_COMMAND.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test: assert integrity codes for rehashed evidence and coverage

Independently rehashed process Evidence and a tampered digest project
evidence_integrity_mismatch. An unsupported comparison operation stays
invalid_request. Unsupported inventory coverage status is an integrity
failure whose reason carries the coverage.status schema issue.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 04:47:39 +08:00
morluto 46217c69bc refactor(rizin): share validated command requests across admission and execution
Resolve raw input at the application boundary and reuse its facts in both MCP admission paths. Keep cleanup, mutation retirement and execution ordering while retaining structured correction details for rejected commands.

Validation: 186 focused tests, source checks, docs conformance and duplication gate passed. The new compiled CLI regression fails on the main baseline. Provider process controls use deterministic fixtures; no real Rizin verification is claimed.
2026-10-23 04:29:35 +08:00
morluto 3e87889bfb test(process): isolate child startup and assert cleanup recovery values 2026-10-23 04:29:25 +08:00
morluto 746a41937d fix(lifecycle): retain Android and Kuna descriptors when close fails (#6363)
* fix(android): retain snapshot descriptors when close fails

Preserve the stable-file diagnosis or completed copy facts when an APK
or engine snapshot close rejects, and retry that exact owner before
workspace retirement.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): retain span descriptors when close fails

Preserve completed span text or the short-read diagnostic when close
rejects, and keep session close incomplete until that handle is released.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): attribute snapshot cleanup to the descriptor that failed

A finished copy can be nested under another descriptor's rejected close.
Walk that chain, keep the snapshot hash on the partial observation, and
name every descriptor that is still open.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): gate span admission until a retained close releases

Overlapping requests can pass the entry cleanup check before any lease
exists. Hold each span open through its close so the next open retries
that descriptor instead of admitting another one.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): preserve nested snapshot facts when both closes fail

Walk nested close failures so a finished copy and a changed-APK diagnosis
survive when the source descriptor also rejects close. Attribute cleanup to
each descriptor that failed, and classify a nested close cancellation.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): release recovered span leases before the next open

Serialize span admission and close without holding the queue across the byte
read. Recheck the caller signal after that wait, and drop a recovered lease
from the resource scope as well as the span map.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): retain a source descriptor when admission close fails

openRegularFile can reject after the descriptor opens. If that close also
fails, keep the owner on the snapshot cleanup map instead of dropping it
when adoption never runs.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): keep cancellation when a completed span close fails

Pass the caller signal into span finalization. If the read already finished
and close then rejects, report cancellation as the primary error and keep
the span text with the retained descriptor.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style: format Android and Kuna close-ownership changes

CI format:check rejected the four files touched by the close-ownership fixes.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): keep the snapshot hash inside a nested cancellation

A destination close that succeeds after abort throws RegularFileCancelled
with the finished copy. When the source close then rejects, recover that
copy so cancellation keeps the digest and file-snapshot-hash observation.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): keep the snapshot hash on a direct close cancellation

A finished copy whose descriptor closes successfully after abort is a
top-level RegularFileCancelled. Attach its digest and file-snapshot-hash
observation to that cancellation.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): preserve the caller abort reason after a successful span close

A completed read whose close then succeeds throws a cancellation wrapper.
Return AnalysisCancelledError with the caller's abort reason instead of
that wrapper.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 03:25:24 +08:00
morluto 93a384db77 fix(evidence): classify derived failures at their owning boundary
Parse caller selections and authenticated Evidence at their owners, reuse the parsed function and comparison facts, and preserve unexpected implementation failures. Remove downstream error guessing and redundant validation wrappers.

Verify with 526 affected tests, source checks, docs conformance, test discovery and duplication checks. Seven public SDK regressions fail on the main baseline. No real-provider execution was performed.
2026-10-23 03:22:34 +08:00
morluto 7091be291c test: repair remaining bulk-merge regression fixtures (#6375)
fix: repair main after bulk merge

Restore typecheck after #3826 called uniqueBy, and align the red fixtures
with the merged pcap, browser, IDA, and Hopper contracts.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-23 03:21:05 +08:00
Paritosh Lahre 3571002422 fix(setup): offer Hopper installation only where setup can install it (#4642)
* fix(setup): offer Hopper installation only where setup can install it

On a host where automated Hopper installation is ineligible (Windows,
macOS below 12 or with an unknown version, or an unsupported or
unidentified Linux distribution), an unhealthy setup without a Hopper
launcher ended by advising "Rerun with --yes --install-hopper", and the
same run then refused that request. The eligibility rule existed twice
(the discovery proposal and the explicit-install gate, with separate macOS
parsers that disagreed on malformed versions), and the final advice
consulted neither.

Make setup discovery the single owner of Hopper install eligibility. The
explicit gate refuses with the unchanged copy through hopperInstallRefusal,
and the final advice offers --install-hopper only where the host is
eligible; ineligible hosts fall back to doctor remediation. hostRemediation
now checks only the Node.js runtime. An empty or unparseable macOS version
is now refused by the explicit gate instead of installing.

Fixes #3944

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: drop merge-only formatter changes

* test: align inherited fixtures with current analysis contracts

* test(ida): assert search recovery instead of diagnostic prose

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 03:17:34 +08:00
David Fontanet Bujaldón 86655eac66 fix(hopper): keep automated Linux setup off non-x86_64 hosts (#3422)
* fix(hopper): keep automated Linux setup off non-x86_64 hosts

Every pinned Linux Hopper package (deb, rpm, Arch) is x86_64-only, but
hopperSetupSupported was derived from os-release alone. Setup therefore
planned and confirmed an amd64 package install on arm64 Ubuntu 24.04 and
the other tested distributions.

Classify installer support with the host architecture where the
distribution is parsed, so setup planning, preflight, installation and
package verification share one decision. Setup now takes its Linux
distribution from the doctor host, as it already does for the macOS
version, and the supported-host remediation text has a single owner.

Fixes #3419

* fix(hopper): install Linux Hopper from the setup host's distribution facts

systemLinuxHopperInstallHost read os-release with process.arch on its own,
while setup planning used the doctor host's injected architecture. Both
agree in production, but a doctor host composed with another architecture
could plan one answer and install with another.

The install host now takes its distribution reader from the caller, and
systemSetupHost passes the doctor host's, so planning, preflight and
installation share one host-fact owner. The unused default host on
installLinuxHopper, the other ambient reader, is removed.

* fix(verify-package): require Hopper readiness only where Linux setup installs it

packageSetupSupport required doctor Hopper readiness on every Linux host
whose host check passed, including installer-untested distributions and,
after the architecture gate, arm64 hosts where setup never provides
Hopper. On Linux, readiness now also requires automated installer
applicability; macOS is unchanged.

This narrows the readiness assertion from #2973 on hosts outside the
installer matrix, such as Kali and ubuntu-24.04-arm.

---------

Co-authored-by: DavidFB-creator <220631175+DavidFB-creator@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-23 02:39:05 +08:00
Can 536f5ce38b fix(browser): preserve source-map media types (#4032)
Co-authored-by: eco-null <eco-null@users.noreply.github.com>
2026-10-23 02:38:56 +08:00
RODRIGO DE SOUZA FARIA b6e6d7cd1a fix(ida): ignore released worker rows when verifying close (#4234)
* fix(ida): ignore released worker rows when verifying close

Upstream idb_list can observe the owning worker mid-teardown and return a
row whose identity is already cleared - empty session_id, owned false,
is_active false - while input_path still names the private copy. The
post-close check matched that row through its private-input arm and threw
"IDA worker remains registered after close.", failing a run whose analysis
had completed and whose idb_close was already acknowledged, and retaining
the private workspace.

Such a row establishes no live session, so it no longer blocks release. A
genuine peer on the same input keeps a session ID and is still reported,
and the session-ID arm is untouched.

Measured against IDA Pro 9.2 on Windows: 11 of 12 stock runs failed this
way; 6 of 6 passed with this change and retained no workspace.

Refs #3056

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ida): suppress released rows only for worker backends

The blanked-identity exception reached a gui row as well, and a gui
session belongs to an IDA instance REA does not control, so a same-input
gui binding could stop blocking release. The observed teardown shape
covers workers only, so require backend "worker" before suppressing.

Adds a regression test keeping a blank-identity gui row on the same
private input reported as a blocker, and moves the three blanked-identity
tests into their own describe to stay within the per-block line limit.

Refs #3056

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor(ida): state the released-row predicate as equality

`owned` and `is_active` are strict booleans in databaseListSchema, so
`!== true` suggested a third possible value that cannot occur. Say what
the row actually asserts.

No behaviour change; the blanked-identity tests cover both directions.

Refs #3056

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-23 02:38:48 +08:00
Rohit Ghumare 6714fb1d02 fix(javascript): preserve ESM path intent and artifact confinement (#2700)
* fix(javascript): preserve legacy ESM directory intent

* fix(javascript): normalize legacy ESM URL directory requests

* fix(javascript): retain invalid package URL evidence

* test(apple): bound cold archive fixture compilation

* test(release): scope preflight schema to selected jobs

* fix(javascript): preserve package URL admission and target facts

* fix(javascript): validate package target structure before URL lookup

* fix(javascript): preserve surrogate identity in structural package URLs

* fix(javascript): isolate structural package URL identities

* fix(javascript): resolve paths after opaque ancestors normalize away

* fix(javascript): confine legacy URLs and retain target provenance

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:34:28 +08:00
Aaditya 92a9591a41 refactor(pcap): give TShark selection and version admission one owner (#3407)
* refactor(pcap): give TShark selection and version admission one owner

The pcap and packet-capture families wrapped the same caller-supplied
TShark with diverging rules. inspect_pcap_* accepted an absolute
REA_TSHARK_COMMAND or tshark from PATH, while inspect_packet_* and the
server availability policy required an absolute REA_TSHARK_COMMAND and
parsed the version banner with a separate regex.

PcapConfiguration now owns the rule: selectWiresharkTool selects an
absolute environment path or the bare name on PATH and refuses relative
values; locateWiresharkTool resolves a PATH selection to the first
absolute PATH entry holding an executable file; parseWiresharkVersion
admits Wireshark 4.x banners for both providers. TsharkCaptureProvider
and the session availability policy consume these facts instead of
reinterpreting REA_TSHARK_COMMAND, so all four tools accept and refuse
the same configurations. inspect_packet_* still resolves, hashes and
rechecks the located executable, and records selection_source in its
tool Evidence.

Host support and resource bounds are unchanged; unifying them is the
next milestone in #3403.

Refs #3403

* fix(pcap): execute the TShark the shared locator selects

resolvePcapTools still returned bare tool names for PATH selections, so
the operating system could run a tool from a relative PATH entry while
the packet tools skipped that entry and selected a different install.

On POSIX hosts, resolve PATH selections through locateWiresharkTool and
run that absolute executable, failing with the existing tshark_missing or
capinfos_missing code when no absolute PATH entry holds the tool. Both
selections are validated before PATH is consulted, so a relative
environment value still reports its own configuration error. Windows
keeps PATH/PATHEXT resolution in the process launcher.

Refs #3403

* chore: restore main's copies of files the merge hook reformatted

The pre-commit oxlint --fix touched two files this PR does not change; keep them identical to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(pcap): share selected tool identity verification

* perf(pcap): retain compact executable identity

* fix(pcap): report missing selected tools clearly

* fix(pcap): read historical capture evidence

* fix(pcap): preserve executable read failures

* test(pcap): cover version refusal and packet-tool availability selection

Address review follow-ups on the shared TShark owner:

- Send a 3.x TShark banner and a non-Wireshark banner through the packet
  provider, pinning the capability-unavailable reason for each and that
  only the version probe ran before refusal.
- Cover the session availability rule for inspect_packet_capture over
  MCP: a PATH-only install and an absolute REA_TSHARK_COMMAND are
  available on Linux, a relative REA_TSHARK_COMMAND is refused even when
  PATH holds TShark, and no absolute PATH entry reports provider_missing.
- Rename the locator test's missing absolute PATH entry so it no longer
  shadows node:path relative.

Refs #3403

* fix(pcap): name the configured path when a selected tool is missing

Resolving the selected executable before launch replaced the runner's
"Cannot run selected tool <path>" refusal with a message that kept the
configured path only in diagnostics, so the public CLI no longer told the
caller which REA_TSHARK_COMMAND or REA_CAPINFOS_COMMAND value to fix and
the pcap CLI boundary test failed. Include the configured command in the
capability-unavailable message and assert it there.

Refs #3403

* test(captures): give the late-cancellation fixture a TShark selection source

The service fixture added on main in 719d56ebf predates the required tool.selection_source field, so its report failed output validation before reaching the late-cancellation path the test covers.

Refs #3403

* fix(pcap): report a probe's pending cleanup when a post-run check fails

When a tool probe returned with its owned process still awaiting cleanup,
a failed post-run executable re-read or identity check threw before run()
reported that cleanup. Probes have no snapshot to carry it, so callers
saw an ordinary error with cleanupIncomplete false while the provider
kept the process and refused the next request.

After the command returns, combine such a failure with the probe's
ProviderCleanupError (cancellation and other command failures keep their
own cleanup outcome). Classify request failures through one
analysisFailure owner shared by run() and executeAdmitted(), and let the
availability probe rethrow any cleanup-incomplete failure instead of
reporting the tool unavailable.

Refs #3403

* fix(pcap): keep a failed executable re-read's cleanup live with the probe's

The combined post-run failure was bound only to the probe's pending
process cleanup. When the executable re-read had also failed to close its
file, the classified failure owned that cleanup, but the combined error's
live cleanupResources omitted the file and could clear cleanupIncomplete
once the process stopped. Bind both the classified failure and the probe
cleanup as dependencies.

Refs #3403

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:34:14 +08:00
HawkForge 2425493e10 fix(native): keep export names ending in a carriage return (#3457)
nm -j and dyld_info -exports end each row with LF. Splitting on \r?\n and
trimming rows treated a carriage return at the end of a symbol name as part
of the line terminator, so the distinct exports "trailing\r" and
"trailing" merged into one entry with the wrong address. Split rows on LF
only and keep trailing text in export rows.

Fixes #3390
2026-10-23 02:33:56 +08:00
Haoran Xu c592ea6bac fix(opencode): override inherited disabled flags (#3469)
Set disabled to false in generated OpenCode V2 registrations so a
lower-priority disabled entry cannot keep approved setup stale.

Cover layered JSON/JSONC refreshes, idempotent setup and doctor readiness,
exact backups, preserved lower settings, malformed-config refusal, and
the exclusion of disabled registrations from automatic maintenance.
Update the native V2 registration expectations.

Fixes #3318
2026-10-23 02:33:38 +08:00
Dragolone 740f107ff9 fix(apple): stop counting single-object NIB connectors as ownerless (#3502)
* fix(apple): stop counting single-object NIB connectors as ownerless

The NIBArchive projection counts every object whose class name contains
"Connector" and has no resolvable NSSource as an ownerless connection
(#2484). AppKit also archives connector classes that annotate one object
and never encode NSSource: tooltips (NSIBHelpConnector), accessibility
attributes (NSNibAXAttributeConnector) and user-defined runtime
attributes (NSIBUserDefinedRuntimeAttributesConnector). Each of them
marked the document's connection coverage partial with
connection_unresolved, raised connection_count, set graph.truncated and
added the "declare no resolvable owner" limitation, although no
connection was dropped. The keyed-archive producer does not treat these
classes as connections.

Skip AppKit connectors that encode no NSSource key. A connector whose
NSSource is encoded but nil or malformed, and every UIKit runtime
connection, is still counted as ownerless.

Across 3924 NIBArchive files shipped with macOS system apps and Xcode,
688 reported this false partial coverage (for example Preview's
PaperKitWindowController.nib, whose only other connector is one outlet);
none do after the change.

* test(apple): keep unusable AppKit connector sources counted as ownerless

Only an absent NSSource marks a single-object annotation. Cover an AppKit outlet connector whose NSSource is nil or a non-reference value, which must still be reported as an unresolved, omitted connection.

* test(apple): split unusable connector source cases into their own block

Keep the connector describe block within the max-lines-per-function limit.

* fix(apple): keep unknown NIB connectors unresolved

* fix(apple): preserve unknown AppKit NIB connectors

* fix(apple): share annotation connector semantics

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:33:26 +08:00
Pirro Zani f33b7bd617 fix(website): wrap mobile navigation at enlarged text sizes (#3598)
* fix(website): keep header navigation on one row and grid it on phones

The header grid gave the navigation only the space left beside the brand
caption and social controls, so six links wrapped onto a second line in
Greek, German, Spanish, Portuguese, Vietnamese and English at common
desktop widths.

- Size the navigation to its content and let the brand column absorb the
  remaining width; a container query hides the caption only when it no
  longer fits, replacing the fixed 851-1250px breakpoint.
- Move the navigation to its own row at 1100px and below, before one
  line can no longer hold it in any edition.
- On phones, lay the six links out as two rows of three content-sized
  columns, with a tighter gap below 340px.

* fix(website): wrap mobile navigation at narrow widths

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:33:08 +08:00
Haoran Xu 4a90059fe2 fix(hermes): detach aliased server tables before editing (#3785)
* fix(hermes): detach aliased server tables before editing

Copy aliased parent mappings before setting or removing a Hermes
registration. Resolve references against the original document and remove
anchors from the private copies to preserve existing sources and consumers,
including shadowed anchor names.

Cover YAML 1.1 and 1.2 setup, refresh, doctor readiness, repeated setup and
uninstall, along with comments, exact backups and invalid-alias refusal.

Fixes #3320

* test(setup): isolate Hermes flows from host Hopper detection

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:32:48 +08:00
윤종근 aa521379dd fix(website): align the language picker chevron (#3805)
* fix(website): align the language picker chevron

Replace the font-dependent down glyph with a fixed-size SVG mask that
inherits the button color and aligns within its existing flex layout.
Rotate the chevron when the native details menu is open.

Refs #3804

* fix(website): preserve the chevron in forced colors
2026-10-23 02:32:29 +08:00
Liu Jie 5d3762456f fix(reconstruction): retain semantic unknowns in obligation ledgers (#3826)
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 02:32:11 +08:00
Anurag Singh 1f9d1b5de1 fix(browser): reject empty capture containers beyond the 64-level nesting budget (#3975)
The shared HAR/qlog JSON parser checked depth before pushing a container
using `frames.length > 64`, which admitted a 65th container. Over-deep
scalars were only rejected because literal values ran the same check, so
an empty array or object at level 65 passed while `[0]` at the same level
failed.

Admit a container only while its own level (root = 1) stays within the
budget and drop the literal-value check, so empty and scalar-bearing
containers share one boundary.

Fixes #3960

Co-authored-by: Anurag Singh <211784907+Anurag-5ingh@users.noreply.github.com>
2026-10-23 02:31:53 +08:00
pablodiazjorge 02e2c9cd7f fix(providers): report provider-selection diagnostics when the selected provider refuses its profile (#4103)
* fix(providers): report provider-selection diagnostics when the selected provider refuses its profile

An explicitly selected provider that refuses the target during profile resolution now yields the target_unsupported selection error with its candidates and rejections, keeping the refusal's message and, when present, its specific recovery.

Fixes #3930

* fix(providers): keep refusal evidence and cleanup ownership on selection failures

A refusal with unconfirmed cleanup is returned unchanged; otherwise the selection failure carries the refusal's captured output, diagnostics, partial observation and cause. Registry tests cover the copied recovery and the cleanup guard.
2026-10-23 02:31:23 +08:00
kuxiaowo 3f35eacad2 fix(website): handle UTF-8 output and slash refs in link audits (#4123) 2026-10-23 02:31:11 +08:00
Chip Li 1ba178befb fix(process): preserve terminal cell widths during normalization (#4142) 2026-10-23 02:30:54 +08:00
dogan 02a0e72f70 fix(sqlite): honor selected-table reply budgets (#4216) 2026-10-23 02:30:36 +08:00
To3akaRin b4bc6cf3ee fix(captures): scope HAR HTTP interpretation to entries (#4351)
* fix(captures): scope HAR HTTP interpretation to entries

* test(snapshot): preserve Evidence-scoped native workflow unknowns

* test(process): assert owned snapshot cancellation outcomes

* test(process): preserve snapshot race causes and owned cleanup

* test(cli): scope runtime cleanup provider injection

CLI boundary tests share a module graph. The cleanup fixture's module mock
cannot replace a provider factory already captured by the real command
registration, leaving its close count at zero after another test imports it.

Inject a typed provider factory into the registration instance, defaulting
to the existing production factory. Both commands still create their own
provider at execution time. Remove the redundant runtime context wrapper
and the global mock state. Keep the real child CLI parity case and verify
that neither command completion nor JSON output precedes awaited cleanup;
retain the close-count, cleanup error and completed Evidence assertions.

The unchanged test passes alone but fails with the command module preloaded.
Both modes pass after the correction. Seven related files pass 28 tests;
check and docs:check also pass on Node24.18.0/npm11.16.0 macOS arm64.

* test(artifacts): use valid ASAR bytes for signature control

* test(mcp): isolate snapshot filesystem fault injection

* test(process): distinguish unacquired resources in failure progress

* chore: restore main's copies of files the merge hook reformatted

The pre-commit oxlint --fix touched two files this PR does not change; keep them identical to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 02:30:06 +08:00
To3akaRin 1684c73d4f fix(artifacts): reconcile ARM32 Mach-O slice names by subtype (#4352)
* fix(artifacts): reconcile ARM32 Mach-O slice names with subtypes

* test(snapshot): preserve Evidence-scoped native workflow unknowns

* test(process): assert owned snapshot cancellation outcomes

* test(process): preserve snapshot race causes and owned cleanup

* test(cli): scope runtime cleanup provider injection

CLI boundary tests share a module graph. The cleanup fixture's module mock
cannot replace a provider factory already captured by the real command
registration, leaving its close count at zero after another test imports it.

Inject a typed provider factory into the registration instance, defaulting
to the existing production factory. Both commands still create their own
provider at execution time. Remove the redundant runtime context wrapper
and the global mock state. Keep the real child CLI parity case and verify
that neither command completion nor JSON output precedes awaited cleanup;
retain the close-count, cleanup error and completed Evidence assertions.

The unchanged test passes alone but fails with the command module preloaded.
Both modes pass after the correction. Seven related files pass 28 tests;
check and docs:check also pass on Node24.18.0/npm11.16.0 macOS arm64.

* test(artifacts): use valid ASAR bytes for signature control

* test(mcp): isolate snapshot filesystem fault injection

* test(process): distinguish unacquired resources in failure progress

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 02:29:48 +08:00
XY b5c47f5255 fix(browser): retain bundle default origin scope (#4413)
* fix(browser): retain bundle default origin scope

* test(browser): cover bundle URLs without origins

* fix(browser): retain validated bundle target origin

* fix(browser): validate recorded origins canonically

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-23 02:29:29 +08:00
Adolanium 7e8ec0e456 fix(browser): keep omitted JSON request bodies out of complete shape coverage (#4476) 2026-10-23 02:29:10 +08:00
amyanger 7436ac8e20 fix(javascript): drop built-in effects for visibly replaced globals (#4565)
The semantic collectors admitted Node timers, fetch, WebSocket, JSON.parse
and global coercions from the identifier spelling alone, so a source that
replaced those globals (`setTimeout = () => null`) still produced resolved
built-in effects. Require the existing isUnmodifiedGlobalReference guard,
which the static analyzer already uses for fetch and WebSocket, before
admitting these effects.

The guard treats any visible possible write as a replacement without
evaluating order or reachability, so computed global writes and guarded
polyfills also remove the resolved effect. The workflow docs now say so.

Fixes #3367
2026-10-23 02:28:53 +08:00
Ganesh de00fdc17d fix(firmware): state that Unblob link targets are extraction-relative (#4573)
Co-authored-by: Ganesh2325 <184471511+Ganesh2325@users.noreply.github.com>
2026-10-23 02:28:35 +08:00
Vinícius Andrade 75575f2006 fix(javascript): keep directory-form HTML URL references distinct from files (#4646)
* fix(javascript): keep directory-form HTML URL references distinct from files

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* test(javascript): cover directory-form HTML URL references

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

---------

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
2026-10-23 02:28:05 +08:00
JG Tromp db8556e724 fix(ida): supervise regex inventory matching (#4862) 2026-10-23 02:27:36 +08:00
pablodiazjorge e3a00bb5f9 fix(setup): tell MSIX Claude Desktop's process view from any private roaming file (#4903)
* fix(setup): tell MSIX Claude Desktop's process view from any private roaming file

Some profiles keep writing the real %APPDATA%\Claude, so the MSIX package never gets a private LocalCache\Roaming\Claude folder and setup and uninstall refused Claude Desktop for good. Compare that folder first and, when it has no file, a bounded set of files from the package's other private roaming folders, which the package redirects in the same way. A package with no private roaming file still refuses, now with the manual edit as the remedy.

Fixes #4278

* fix(setup): address review findings on the MSIX roaming probe

Name the configuration setup would write, and both package files for uninstall, in the unknown-view advice. Bound the roaming walk by 1024 inspected entries and a queue no longer than the directories it can still list. Count ENOENT at the AppData path as a direct view only while the private file still exists.

* fix(setup): bound the roaming walk's directory listings by its entry budget

Read at most the names the walk's budget has left, with opendirSync in production, so a crowded package-private folder is never enumerated whole before the budget applies.

* fix(setup): recheck the private probe before accepting a mismatched target

A private file deleted between the two lookups no longer shadows its AppData path, so a redirected view can reach an ordinary copy there. Count a different target, like ENOENT, as a direct view only while the private file still exists.

* fix(setup): repeat the AppData lookup before trusting a rechecked probe

A private file deleted and recreated between the lookups passed the existence recheck on stale evidence. Look the AppData path up again after the recheck: a match with the private target is a redirected view, an agreeing non-match counts as direct, and a probe whose lookups disagree decides nothing.

* fix: bound Claude roaming folder probes

* fix(setup): charge enumerated Claude folder names

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:27:18 +08:00
Saim Shafique af42f856ec fix(hopper): shut down the Linux demo helper orderly so its X lock is removed (#4966)
* fix(hopper): shut down the Linux demo helper orderly so its X lock is removed

Teardown SIGKILLed the helper's process group, so run_launch's finally
never ran stop_process on Xvfb and each session orphaned its
/tmp/.X<n>-lock. Later startups count orphans as address_collision.

Ask the helper to stop first: closing its stdin trips OwnerLifetime,
and its finally stops Hopper and Xvfb with SIGTERM, which removes the
lock. Anything still alive after the grace period is reaped by the
token-verified group cleanup.

Fixes #4921

Co-authored-by: Saim Shafique <128062316+sx4im@users.noreply.github.com>

* fix(hopper): notice signal-exited demo helpers during orderly shutdown

A helper that already died from a signal keeps exitCode null, so the
orderly-shutdown path treated it as still running and sat out the full
grace period before the group cleanup. Check signalCode alongside
exitCode in both the cleanup guard and the exit wait, and add a
regression test for an already signal-exited helper.

Also hardens the ignored-shutdown test: it now proves the fixture
started (waits for its lock), asserts the helper was reaped by the
group SIGKILL, and bounds the wait by the configured 500 ms grace
instead of a vacuous 30 s ceiling.
2026-10-23 02:26:58 +08:00
Devulapalli Naga Sri Vaishnavi 809f3b7b5b fix(browser): ignore scenario storage enumeration order (#5035)
* fix(browser): ignore scenario storage enumeration order

* perf(browser): sort storage entries without serialized copies

* style(browser): format storage normalization comparator

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:26:41 +08:00
NIKHIL 9a21cd78ce fix(javascript): preserve inherited aliases past erased class fields (#5040) 2026-10-23 02:26:24 +08:00
berce be4498d394 fix(gdb): accept GDB's built-in p, s, d and t aliases (#5124)
The one-shot output-route check read the first word as an abbreviation,
so `p 1`, `s` and `d 1` matched python, source and define, and `t 1`
matched tty, and were refused before GDB started. GDB resolves its
built-in aliases first, so resolve the four that shadow those prefixes
(print, step, delete, thread) in one helper both checks share.

Fixes #5098
2026-10-23 02:26:06 +08:00
rodricksz4h5 5d3ae66e63 fix(javascript): match unchanged module exports across application versions (#5196)
* fix(javascript): match unchanged module exports across application versions

An export binding's identity is keyed within its whole application root (container_sha256), so it changed whenever any sibling file changed, and no match tier paired export nodes: every export of an unchanged file was reported removed and added, and its module fell to unknown. The exact module-source-digest tier now also pairs an export binding by its own file's bytes (identity artifact_sha256) and exported name, as it already pairs a source module by source_sha256. Exports of edited files stay unmatched.

* style(javascript): format the version-matching export test

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-23 02:25:43 +08:00
Dery Ferdika 26573c3aa4 fix(hopper): bound bridge request frames like the Cutter bridge (#5262)
* fix(hopper): bound bridge request frames like the Cutter bridge

The Hopper bridge read each request with an unbounded readline, so a peer
that never wrote a newline kept Hopper allocating for as long as it kept
writing. The Cutter bridge already refuses a frame above MAX_FRAME_BYTES;
the Hopper bridge had no request ceiling at all.

Read the request line with a 16 MiB bound and refuse a line that fills the
limit without a terminator, using the existing invalid_request diagnostic
before closing the connection. Such a line cannot be answered or
resynchronized, because its remainder would be read as the next request.
The response direction is unchanged, so large decompilation results still
flow, and every dispatchable method carries small bounded parameters.

The stalled-line case keeps its connection open instead of half-closing
it, so the test pins the exact ceiling: a bound one byte larger waits for
a byte the peer never sends and fails instead of passing quietly.

Validation: npm run check:fast (typecheck, lint) passed uncached, and the
new boundary test passed against the real bridge over socket pairs at the
frame limit and above it. Removing only the read bound makes the same test
fail, and widening the bound to one byte past the limit fails it too. The
Hopper boundary and bridge-packaging suites report the same 17 failing
files and 126 failing tests before and after this change on this Windows
host; those failures are POSIX-only probes (Unix socket directories,
os.statvfs) unrelated to this diff. Native macOS Hopper and real-client
traffic were not run.

* fix(bridges): exclude line delimiter from payload limit

* test(hopper): cover partial request at EOF

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:25:24 +08:00
곽현 b2048d46d1 fix(process): retain unresolved descendants during lineage observation (#5270)
* fix(process): retain unresolved descendants during lineage observation

* fix(process): preserve lineage across ancestor generation changes

* fix(process): avoid retaining replacements of exited candidates

* test(cli): avoid unused cache writes in module trace acceptance

* fix(process): retire replaced lineage candidates

* fix(process): preserve uncertain owners and validate launcher scope
2026-10-23 02:25:04 +08:00
You Wish 8ecbb74b00 fix(wasm): refuse unretained summary delivery before provider work (#5274)
* fix(wasm): refuse unretained summary delivery before provider work

inspect_wasm_artifact with detail summary ran the WASM provider before
checking whether the server retains Evidence. On a fixed server without
session retention a successful provider run was followed by
capability_unavailable, and a failing provider run replaced that
diagnostic with the provider error, hiding the guidance to select
detail complete.

Check retention right after input validation, as the EVM, pcap and
network-capture handlers do, so the refusal precedes any provider work
and keeps its typed diagnostic. Complete delivery is unchanged. The
fixed-server boundary test now injects a vi.fn provider and asserts it
stays idle for refused summaries while complete delivery still runs it.

Fixes #5100

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(wasm): validate caller paths before the summary retention preflight

Review follow-up for #5274. The retention preflight ran ahead of the
semantic input checks, so a relative path, glue path or candidate path
with detail summary on a fixed server returned capability_unavailable
instead of its field-specific invalid_request.

WasmArtifactService now exposes that parse-and-absolute-path step as
validate(); inspect() uses the same method, so the checks stay at the
owning boundary, and the MCP handler validates before deciding on
retention. The composition descriptor and server typing expose validate.

The fixed-server boundary test sends relative path and glue_paths with
detail summary and asserts invalid_request with both issue paths and no
provider call; it failed on 418a66d7d with capability_unavailable.

docs/mcp-contracts.md now claims the before-analysis refusal only for
inspect_artifact, inspect_wasm_artifact, inspect_macho and
decode_interface_builder, which enforce it; inspect_binary_layout and
analyze_javascript_application still analyze first and are left to a
separate change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(wasm): inspect validated artifact input without reparsing it

Follow-up for #5274, matching the review outcome on #5288. The MCP
handler validated the request and then called inspect(), which ran the
same validator again, so every call parsed and cloned its input twice.

WasmArtifactService now separates the raw entry point from execution:
inspect() validates raw input once and delegates to the new
inspectValidated(), which runs the inspection for input that validate()
already admitted. The handler validates, runs the retention preflight,
then calls inspectValidated(); the composition descriptor and server
typing expose it. The CLI keeps the raw inspect() entry point; behavior
and diagnostics are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(wasm): keep cancellation ahead of raw artifact input validation

Follow-up for #5274, matching the review outcome on #5288. Separating
validate() from inspectValidated() moved the raw inspect() entry point's
validation ahead of its abort check, so a direct call with an
already-aborted signal and malformed input returned AnalysisInputError
instead of the AnalysisCancelledError the pre-change service gave.

The raw entry point now checks the signal before validating, as before,
while inspectValidated() keeps its own guard for the MCP handler path.
A unit test pins the precedence with no provider call.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:24:45 +08:00
Vishal Tambi 9c81191b1d fix(ghidra): treat format-specific disabled analyzers as not applicable (#5425)
* fix(ghidra): treat format-specific disabled analyzers as not applicable

* test(json): assert composed cancellation cleanup for staged output

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-23 02:24:16 +08:00
Yann Roberto 220414682e fix(setup): preserve explicit clients with all-detected selection (#5508)
* fix(setup): preserve explicit clients with all-detected selection

* test(filesystem): align staged cancellation cleanup assertions

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-23 02:23:58 +08:00
Wade d11fca46fc fix(cli): print compact mcp doctor JSON when stdout is redirected (#5514)
rea mcp doctor rendered json with Formatter.format, which always indents, so
redirected --json, --full-output and validation errors stayed indented. The
dispatcher now passes the stdout TTY state and the doctor renders json and
jsonl through jsonOutputParts like the other commands.

Fixes #5435

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-23 02:23:39 +08:00
吴佳浩Alben 5c8d5b2a8a fix(hopper): keep an observed launcher exit over a later cancellation (#5816)
* fix(hopper): keep an observed launcher exit over a later cancellation

`#connect` projected every interrupted wait as `#startupInterruption`
without consulting the launcher the owner already held, so a launcher that
exited 3 before the caller aborted was reported as `HopperCancelledError`.

An exit or signal the owned process already holds is now projected as the
physical startup failure first; a cancellation observed before any exit is
unchanged, and successful exits keep their previous behaviour.

Fixes #5429

* fix(hopper): arbitrate startup exits through process owner

---------

Co-authored-by: XiaoBinGan <XiaoBinGan@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-23 02:23:16 +08:00
amyanger 87657c6297 fix(model): admit safetensors header lengths that resemble pickle markers (#5918)
A safetensors length prefix such as 640 encodes as 80 02 00 ..., which the
provider read as a pickle PROTO marker and refused before the safetensors
parser ran. The parser that owns the length prefix now makes the call: a
pickle-like prefix is safetensors only when byte 8 is '{' and the declared
length is within the safetensors header ceiling. Real pickles stay refused
and are never deserialized.

Fixes #5895
2026-10-23 02:22:58 +08:00
Vinícius Andrade af73951405 fix(artifacts): refuse thin Mach-O extraction before inventory (#6152)
* fix(artifacts): refuse thin Mach-O extraction before inventory

Extraction admitted both Mach-O formats and fell through to the universal
slice reader for a thin file, which yields a slices/<arch> entry that the
root-only inventory never recorded. The writer then reported an integrity
mismatch and recommended an integrity policy retry that cannot succeed.

Only mach-o-universal has an extraction reader, matching the inventory
reader selection. A thin Mach-O now receives the typed unsupported-target
refusal before any inventory or output work.

Refs #6098

* test(artifacts): cover the thin Mach-O extraction refusal

A thin arm64e Mach-O image is refused with the typed unsupported-target
error and no output directory is created.

Refs #6098

* fix(artifacts): keep embedded packs behind a thin Mach-O extractable

Refusing every thin Mach-O before inventory also refused PyInstaller
onefile executables and embedded Godot packs whose bootloader is a thin
Mach-O. Inventory classifies those roots as pyinstaller or godot-pck, and
createReader selects that reader before the Mach-O fallback, so they were
extractable on the parent revision.

A thin Mach-O now takes the same embedded-pack probe as ELF and PE: a
detected pack proceeds to inventory, and a plain image keeps the
unsupported-target refusal.

Refs #6098

* test(artifacts): cover a thin Mach-O PyInstaller onefile extraction

Refs #6098
2026-10-23 02:22:42 +08:00