Scope main pushes from a successful ancestor so canceled runs cannot hide changes. Keep the complete portable suite in fast feedback and move coverage plus Intel macOS to hourly, manual, explicit-full, and release qualification. Let qualification finish independently of superseded feedback.
Bind publication to full qualification at its exact revision and publish the verified tarball after checking workflow identity, version, and SHA-256. Keep trusted cache writers and reject incomplete merged test inventories.
Validation: 151 focused CI tests; typecheck/lint; actionlint 1.7.7; knip; all 1044 files discovered; bounded blob/merge smoke; macOS package verifier with retention and cleanup; npm pack dry run. Native Linux/ARM/Windows and remote workflow execution remain CI verification.
* fix(windows): preserve caller affinity only within one processor group
`spawnProcess` read the caller's affinity mask and applied it to the
suspended child unconditionally. A mask names processors relative to one
processor group, and Windows assigns each new process to a group of its
own choosing, so on hosts with more than 64 logical processors the child
is often placed in another group. `SetProcessAffinityMask` then rejects
the mask with ERROR_INVALID_PARAMETER (87) and the spawn fails, making
every owned provider process start intermittently on such hosts.
Affinity is a nicety, not an authority or isolation control, so it is now
applied only when the caller and the suspended child both occupy the same
single processor group. A child placed in another group keeps that group's
default affinity and the spawn proceeds. Job Object membership,
kill-on-owner-close policy, owner normalization and priority preservation
are unchanged, and the mask failure remains fatal within a shared group,
where it is not expected.
Single-group hosts, including every host with 64 or fewer logical
processors, are unaffected: `GetProcessGroupAffinity` reports one group
for both processes and the same mask is applied as before.
The optional process-boundary fixture gains an `affinity` observation,
and the native verification lane asserts that an owned spawn succeeds and
that the child's mask matches the caller's whenever both share a single
group.
Fixes#2181
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(windows): refuse to widen a pinned caller's affinity across groups
Addresses review feedback on the first commit.
An unconstrained caller loses nothing when Windows places an owned child
in another processor group, so that spawn proceeds with the group's
default. A caller deliberately pinned to fewer processors than its group
holds is a different case: silently accepting the default would hand the
provider tree the whole group, which `docs/installation.md` tells
operators to rely on affinity to prevent. Such a spawn now fails naming
the constraint instead. `GetProcessAffinityMask` already reports the
group's active set, which distinguishes the two without another query.
Selecting the caller's group at creation through
PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY was tried first and rejected:
`CreateProcessW` fails with ERROR_INVALID_PARAMETER on a host with a
single processor group, both alongside PROC_THREAD_ATTRIBUTE_JOB_LIST and
on its own, so it cannot carry the ordinary path.
The boundary fixture's affinity observation now reports a process id's
own mask rather than its own, because a separate probe process is
assigned its own group and cannot stand in for the process that spawns
the child. Masks and the group's active set cross as fixed-width
hexadecimal strings: a mask can set bits above the safe-integer range,
where `JSON.parse` would round two different masks to one value.
The verification lane asserts the mask is inherited exactly when caller
and child share a group, and otherwise that the caller was unconstrained.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(windows): record what owned-process affinity does not preserve
A mask covering its group's whole active set does not distinguish a
caller the system placed in that group from one that selected the group
deliberately, so an owned child can still be placed elsewhere with its
processor count bounded and its group placement lost. Treating that case
as constrained instead is not available: on a multi-group host an
ordinary process is assigned a group by the system and its mask is that
group's active set, so refusing it would fail every owned spawn there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Bind the owned demo helper to REA's private stdin stream and unwind child
cleanup on EOF during startup or analysis. Verify graceful and SIGKILL owner
exit through real CLI/MCP workflows and preserve unrelated processes.
Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Summarize saved Wireshark4.x captures with enforced native resource limits, serialized admission, stable snapshot verification and retained fact/text pages. Preserve complete inventories within resource budgets and source uncertainty; report cleanup failure with partial Evidence and retained ownership.
Verified six recorded corpora /13026 packets with independent Scapy/Python oracles, real CLI/MCP/schema parity,60 SNI names,132 DNS addresses and1000 URIs. Real TShark CI now exercises summary/paging. Actual Windows/Bun Wireshark remains unverified; macOS capture requires a separate enforceable-bound decision.
Co-authored-by: 3QL <85309073+3QL@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Follow-up to #2345; thanks to @gefrezim for the import-time home lookup diagnosis.
Normalize only an empty Windows USERPROFILE before runtime dependency imports, preserving all nonempty caller selections. Reuse the existing public setup dry-run regression in the Windows curated CI lane. No additional filesystem query, engine call, cache or retry.
Verified real Windows Node 24.18.0 CLI unset/empty/selected-profile controls, setup dry-run home selection and unchanged configuration, and baseline/candidate SDK stdio MCP catalogue parity. Nine related tests and static/docs checks passed. No IDA or Ghidra engine was used. Scoped resource observations and measurement limits are recorded in experiments/analysis-efficiency/windows-empty-profile.md.
Fixed the review finding and original CI package-scope ownership failure. Current-head CI is green; the unrelated MCP identity timeout passed on a failed-job rerun without changing its code or timeout. Current-head review completed with no further findings.
Reuse the domain ZIP format list for session schemas, verify full Harmony
CLI/MCP lifecycles, and correct native view guidance and audited docs drift.
Refresh locked dependency notices and gate inventory/provenance consistency,
including notice inputs in the cached documentation gate.
Fixes#2454
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Fixes#2257. Thanks to @chqcjq for the native self-test retry diagnosis in #2266.
Preserve retry disposition through analysis workflows. Native warm admission requires exact sharing/lock codes and affirmative pre-allocation evidence; cleanup ownership takes precedence. No automatic retry or new analysis cache.
Verified with real Windows 11 CLI, same-connection SDK MCP normal/conflict/recovery, the Windows native verifier, 99 focused tests and static/docs gates. Official npm 11.16.0 launcher sources were the application input. No IDA or Ghidra engine was used for this change. Win32 5 was not reproduced; no resolution claim for #1701/#2196. Performance measurements and limits are recorded in experiments/analysis-efficiency/windows-runtime-retry.md.
Inspect bounded recorded raw HTTP/XML SAZ archives and page retained capture Evidence. Preserve exact stored bytes and provenance, validate ZIP/XML integrity, and require an enforceable decoder memory bound.
Verified 356 real recorded sessions against independent byte and metadata oracles, public CLI/MCP parity, retained pages, and related interface checks. Current Fiddler Everywhere GUI and non-Linux producer workflows remain unverified.
Co-authored-by: zahhak <1792039+zahhak@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Reject native callee successes without an explicit truncation marker while preserving provider failure reasons. Verify positive procedure inventory/search and function-result parity in the real-provider lane; support independent string/xref oracles and label their absence as unverified.
Verified with Windows IDA Pro 9.3: eight normal production CLI/MCP checks passed, and six real-provider response-fault cases reproduced old false positives and validated the correction. Windows IDA Free was not used. No personal paths or license registration information are included.
Repair inconsistent complete-file Ghidra test probe sizes after the shared ELF-header validation change, deriving sizes from the fixture buffers. Reproduced the three failures before the correction; 115 related installation/doctor and ELF tests pass afterward. Runtime parsing and installation behavior are unchanged; no real-Ghidra verification is claimed.
207 focused IDA tests and static/documentation checks passed. Automated review completed on d1e0b1095 without findings. CI run 38327862093 passed all 36 jobs, including Windows, all six test shards, coverage/timing, and real Apple CLI/MCP workflows.
Follow-up to #1544.
@modelcontextprotocol/client 2.3.1 declares callTool(params, options).
Three verifiers still used the v1 shape callTool(params, undefined,
{ timeout }), so the third argument was dropped and those calls ran
under the SDK's 60 s default instead of the 150-180 s they request.
Pass the options second.
* fix(native): honor Mach-O chained pointer locations and library ordinals
Walk declared page starts and next links before decoding chained pointers,
preserving plain pointers between fixups, zero-offset rebases, and known
facts in malformed chains. Interpret positive dylib ordinals with dyld's
special-ordinal cutoff so valid dependency provenance is retained.
Give the Swift verification fixture an explicit module name so link-mode
filenames do not produce invalid identifiers.
Validation: 46 focused regressions; pre-fix reproductions in an isolated
copy; real macOS CLI/MCP verification of 10 compiled Objective-C/Swift,
arm64/arm64e, chained/legacy and symbols/stripped fixture variants.
* perf(native): reuse parsed Mach-O chain membership
* test(native): validate parsed-chain repair against local gates
* test(native): pin chained fixup page failure provenance
* fix(native): bound parsed chained page facts and metadata
* test(server): pin shared partial Evidence provenance
---------
Co-authored-by: baron <richstyles@gmail.com>
Use the existing pinned cross-spawn dependency at the command-spawn boundary instead of forcing every Windows executable and argument vector through cmd.exe. Preserve native executable arguments while retaining PATH/PATHEXT and command-shim support.
Validation: public runner argv and lock/cancellation tests passed on POSIX. Windows-only tests cover an executable path with spaces, bare node, npm, and the local turbo shim; native Windows execution remains unverified.
Fixes#2319
Resolve each caller-selected Electron path once at the application boundary, collect field-specific failures with original causes, and pass canonical paths directly to the provider. Update direct provider consumers and route the real verifier through the shared application workflow.
Validation: public CLI/MCP invalid-path acceptance, canonicalization boundary, provider tests, and cancellation/cleanup checks. Live Electron launch was not verified. This does not address the separate Playwright launch-rejection crash in #2269.
Fixes#2272
Validate unmapped segment file ranges without adding virtual mappings or fallback metadata addresses. Keep mapped-segment bounds and reject build-info sections declared in unmapped segments.
Validation: real unstripped Go 1.26.5 Darwin arm64 and amd64 artifacts passed CLI/MCP oracle, Evidence, source-range and unchanged-byte checks. Retained malformed-input regressions; removed the weaker synthetic acceptance test. Full cross-platform verifier not run. Fixes#2167.
Inspect selected fields in existing captures through shared CLI/MCP Evidence.
Page matching frames without changing dissection or two-pass read coverage;
retain failed descriptor/process cleanup ownership and reject excess admission.
Verified with real TShark 4.0.17 and 4.2.2, public Wireshark recordings,
owned HTTP application traffic, real CLI/MCP workflows and schema checks.
Co-authored-by: Olorinm <59321404+Olorinm@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Add an explicit attached native IDA MCP compatibility profile while preserving the legacy and headless workflows. Keep recorded input identity, complete source observations and the user's open GUI database. Batch unique callee lookups, conservatively prefilter literal strings, preserve Unicode matching and unavailable caller coverage, and require distinct-function switching in native verification.
Verified with Windows IDA Pro 9.3 and the native MCP plugin built from c9d15d98e8a143fc74f6e14037c48f63889b6d6c with a loopback listener. Production CLI/MCP and an unchanged Windows whoami.exe passed. Windows IDA Free was not used. No personal paths or license registration information are included.
Validation: 200 focused tests, static and documentation checks, architecture guards and discovery passed. Historical same-main warm task measurements improved from 675 to 317 ms; response token estimates fell from 16618 to 11509. Fresh-start, overall CPU and memory improvement were not established. Detailed scope is in experiments/analysis-efficiency/ida-native-windows.md.
Co-authored-by: imissapixel <140405963+imissapixel@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Add offline SQLite database/WAL inspection through the shared CLI/MCP.
Use compact inventory, selected-table schema, exact ordered columns and
bounded row samples while preserving source identity and lossless values.
Retain completed Evidence through late cancellation and private-root cleanup
failures, bound concurrent inspections, and recheck journal validity after
acquisition. Reuse prepared CI runtime artifacts across supported Node lines.
Co-authored-by: Y0UW1SH <29498139+Y0UW1SH@users.noreply.github.com>
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Let the fixture lifecycle own CDP readiness with the same 60-second startup deadline as the broader browser verifier. Return the discovered port to both consumers and clean up failed startup before returning a lease.
Validation: five startup/cleanup boundary tests, npm run check, and real Chrome 154 runtime and source-map CLI/MCP verifiers passed on macOS arm64. Hosted Linux verification follows the push.
Keep static feedback concise while retaining complete diagnostic reports,
visible lint errors, module-boundary checks, and the 3% duplication gate.
Upload complete reports after static failures and restore their outputs
from Turbo caches. Preserve unambiguous, checkout-relative clone locations.
Bind both lint caches to the website, documentation configuration and
experiment sources actually scanned by oxlint, including ignore policy.
Guard this ownership by comparing live checker discovery with resolved
Turbo inputs. A real website syntax error now invalidates a cached pass.
Validation: full current-head CI and the separate Go lane passed. Seven
real-checker regressions passed; failure-status and stale-report mutations
were rejected, and restored source passed. Actual Turbo restored both
reports byte-for-byte; full static/docs/workflow checks passed.
Closes#2238.
Refs #2190.
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* feat(ghidra): admit RISC-V ELF analysis through a pinned generic lane
Refs #2063.
Recognize `EM_RISCV` (243) as a provider-neutral family that carries its own ELF
facts, and bound the first Ghidra lane to little-endian `ET_EXEC` images that
declare the double-float ABI, pinned to `RISCV:LE:32:default` or
`RISCV:LE:64:default` with the `gcc` compiler specification.
Ghidra 12.1.4 is not reliable without the pin: its `riscv.opinion` pins
`variant="default"` for the 64-bit constraint and leaves the 32-bit constraint
with the comment that the loader "must choose between 'default' and 'AndeStar'
variants". Measured on the installed release tree, a source-owned generic RV32
ELF with no Andes declaration imports as `RISCV:LE:32:AndeStar_v5:gcc`, while
RV64 resolves to `RISCV:LE:64:default:gcc`. The lane therefore states the
language per width and refuses any caller-selected processor outside it instead
of inheriting the header guess.
Refusals name the declaration rather than falling back to a guessed profile:
big-endian images (Ghidra 12.1.4 ships no big-endian RISC-V language),
non-`ET_EXEC` images, `EF_RISCV_RVE`, `EF_RISCV_TSO`, and every float ABI other
than double, which the pinned generic compiler specifications model. The raw
e_flags bits stay in Evidence as declarations, not as instruction semantics.
Family recognition now has one owner for the ELF-metadata families:
`ELF_METADATA_ARCHITECTURES`, `isElfMetadataArchitecture`, and
`HeaderArchitecture` replace ten `Exclude<BinaryArchitecture, "mips">` sites that
would each have needed a second hand-edited member. `ghidraPinnedLanguage` is
that owner for the import commitment: the session readback previously re-derived
only the MIPS pin, so a profile committing any second pinned language failed with
a language-mismatch error before the bridge started.
Hopper and IDA refuse RISC-V by name, matching the MIPS wording. Caller-supplied
raw-binary entry keeps its existing four-family list; this lane is ELF-header
admission only.
Verification on macOS 15.7.7 arm64, Node 24.18.0, Ghidra 12.1.4 PUBLIC and JDK
21.0.12.1, with the host decompiler built from the release sources for
`os/mac_arm_64`: `npm run check` passes; `npm run test:fast` passes 396 test
files; `npm run verify:test-discovery` discovers all 917 test files exactly once.
Source-owned RV32 and RV64 double-float `ET_EXEC` fixtures complete
`rea analyze --provider ghidra` and `rea decompile rea_riscv_entry`, committing
`RISCV:LE:32:default` and `RISCV:LE:64:default` with `language_selection:
provider-pinned-v1`; the soft-float RV64 shape is refused with the named
float-ABI reason, and the full refusal matrix including the RV32 and
width-mismatch shapes is covered by unit tests. No `verify:ghidra:riscv` lane
script is included in this change; the runs above were performed manually against
the installed engine. Fork pull requests receive no CI check runs, so the
real-provider scope above is the evidence available for review.
* fix(ghidra): bound the RISC-V lane by declared flags and document it
Address review feedback on #2151.
`e_flags` bits outside `EF_RISCV_RVC | EF_RISCV_FLOAT_ABI` are now refused with
the offending value named, so a reserved or newer producer declaration cannot
enter the verified generic lane by falling through the RVE, TSO and float-ABI
checks.
Admission reads `e_type` only, so the refusal text no longer calls `ET_EXEC`
static: a fixed-address declaration does not establish static linkage, and
`PT_INTERP` and dynamic dependencies are not inspected. The session records that
boundary as a limitation rather than inferring a load model.
Add `docs/ghidra-riscv.md` in the shape of the MIPS lane guide (admission
boundary, refusal table, why the language is pinned per class, Evidence fields,
and what the fixtures do not establish), and correct
`docs/firmware-analysis.md`, which still told users that MIPS and RISC-V
decompilation had not been added.
Verification after the change: `npm run check` and `npm run docs:check` pass; the
RISC-V module tests pass (17 lane cases plus 9 parser cases); on Ghidra 12.1.4
with JDK 21.0.12.1 the RV32 and RV64 double-float fixtures still analyze and
decompile with `RISCV:LE:32:default` / `RISCV:LE:64:default` and
`language_selection: provider-pinned-v1`, the soft-float fixture is still refused
by name, and the new linkage limitation appears in the emitted Evidence.
* fix(ghidra): align RISC-V pinning with admission
Reuse the complete lane admission boundary when selecting a language, retain unsigned unsupported flag bits in diagnostics, and derive float ABI metadata from the source declaration.
* test(ghidra): verify RISC-V CLI and MCP workflows
Build source-owned RV32/RV64 fixtures with Clang and LLD, establish independent ELF and symbol facts with LLVM readelf, and verify real provider evidence, instruction bytes, calls, decompilation, schema projections, snapshot replay, refusal diagnostics, source immutability and cleanup.
Verified on macOS ARM64 with Ghidra 12.1.4, JDK 21 and LLVM/LLD 23.1.2. Dynamic linkage, big-endian, Andes and RVE/TSO workflows remain unverified; ISA attributes are not inspected.
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Run the existing README consistency and Python producer guards from their
CI owners. Execute full local validation fresh while preserving cached
preparation, and permit scoped reuse of earlier portable build entries.
Collect failed-shard diagnostics before enforcing success and publish
compact, portable timing history only after a complete successful merge.
Preserve installer truncation failure across supported Bash versions.
Keep cancellation tests focused on the called MCP tool, observe server
progress before timing target readiness, and retain delayed-startup,
cancellation, cleanup, and live follow-up request assertions.
Validation: all 32 CI jobs and the separate Go lane passed; 935 files,
9,630 cases, 9,544 passed, 86 skipped, zero failed. Controlled regressions
and fault/restoration probes are recorded in PR #2210.
Refs #2190.
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
* feat(flutter): identify Dart snapshot builds by pure APK parsing
Add a flutter-provider family with one operation, identify_flutter_build,
that reads an APK's lib/<abi>/libapp.so and libflutter.so through the
hardened ZIP reader and reports build facts as observations:
- The Dart VM snapshot hash, read 20 bytes after every snapshot magic
(f5f5dcdc). The vm and isolate sections are cross-checked: agreeing
sections collapse to one snapshot_hash, disagreeing sections keep every
candidate with snapshot_hash null and partial coverage.
- Per-ABI library digests and byte sizes, plus the engine library's GNU
build-id note and any labeled 'Dart VM version' or Android clang/LLVM
toolchain strings, verbatim; release builds without a version string
report null rather than a guess.
- The APK is digested before parsing so Evidence binds the observation to
the exact input, and a target with no libapp.so reports not-detected
with complete coverage.
The scanner is streaming with explicit pending-magic and rescan
bookkeeping, so chunk boundaries cannot double-count or drop sections, and
magic-free streams never accumulate. No engine, no external lookups: the
hash-to-SDK mapping stays with external datasets by design.
Verified against Flutter Gallery 2.9.2 (112 MB, three ABIs): every ABI
reports the same agreeing hash 65817c30a78bb44c3dc3771876b6010a from two
sections, per-ABI build-ids, and the clang toolchain line; a plain
aapt2-built APK reports not-detected with complete coverage. Scanner
goldens come from the same libraries. READMEs carry the new 'Flutter apps'
row in every supported language.
* feat(flutter): inspect Dart AOT snapshots through the ELF symbol table
Add inspect_dart_aot to the flutter family: for one ABI's libapp.so it
locates the four _kDart*Snapshot* symbols through the ELF dynamic symbol
table (ELF32 and ELF64 little-endian, bounds-checked reads; a payload
without exported symbols is refused), reports each section's offset and
size, validates data-section headers (magic, kind, length; instructions
sections honestly report nulls for the fields their layout does not
carry), and projects a bounded string pool from the isolate data section:
distinct package: source URIs (the app's dependency inventory), dart: SDK
URIs, and identifier-shaped tokens, each with counts, bounds, and partial
coverage when truncated.
The string pool is labeled as a byte-pattern projection, not deserialized
cluster semantics: typed class and function recovery remains an
SDK-specific parser, which the snapshot hash now unlocks. The ABI is
caller-selected with a deterministic default (arm64-v8a, x86_64, then
first available).
Verified against Flutter Gallery 2.9.2: all four symbols on both ELF64
(arm64-v8a) and ELF32 (armeabi-v7a) images, header validation, hash
agreement with identify_flutter_build, and a 756 package: / 201 dart:
URI pool from the isolate data section; goldens in DartElf.test.ts come
from the same libraries.
* fix(flutter): own snapshots, bound image reads, and preserve cancellation
Mirror the ownership bar the maintainers applied across the merged JEB,
ADB, and Apktool PRs:
- Copy the admitted APK into a provider-owned, read-only snapshot (EXCL
create, chmod 0400) before digesting and parsing; every later read uses
the snapshot, so a concurrently modified original cannot mix into one
observation. The result reports the snapshot's byte size and digest.
- Retain failed snapshot-root cleanup in a provider set and retry it on
close(), throwing an aggregate error when a root is still owned; root
removal is injectable so the retention is testable.
- Allocate the AOT image buffer at exactly the declared library size
before reading (bounded before allocation, not concat-after-stream),
keep the 256 MiB ceiling, and check cancellation between digest and
stream chunks through a captured abort reason.
- Accept APK paths containing spaces (covered by a fixture test) and
escape the ABI pattern's dash for v-mode regex compatibility.
Also add tests for cleanup retention with close retry and for
cancellation before any snapshot root is created.
* docs(flutter): cover the Italian README with the Flutter row
The Italian translation landed between the merged feature PRs; its table
now carries every merged row plus this one, keeping its documentation-link
set identical to README.md.
* fix(flutter): make the ABI pattern portable for v-mode validators
Use a hex-escaped hyphen in the ABI character class, matching the form
the ADB portability fix uses, so clients compiling advertised schemas in
unicodeSets mode accept the inspect_dart_aot input schema.
* refactor(flutter): reuse shared harnesses and deduplicate the vertical
The duplicate-detection gate (jscpd, 2.5% threshold) tipped to 2.51% with
the flutter files added. Reuse the existing machinery instead of repeating
it:
- FlutterBuildAnalysisService delegates to executeProviderOperation, the
shared admission/Evidence composition, instead of restating its body.
- The CLI registers both commands from one table-driven spec.
- Boundary tests use the shared serveCli and assertAdvertisedMcpContracts
harnesses rather than hand-rolled equivalents.
- The provider test consolidates the four payload-shape cases into one
table-driven case; the service test uses one admission table and
distinct phrasings.
Duplicate lines fall from 2.51% to 2.48%, back under the gate.
* fix(flutter): address review findings from real-app verification
CassieFox23 verified the PR against three real F-Droid Flutter apps and
a control app, and found five gaps. All are fixed and re-verified against
cone (info.tangential.cone), one of the tested apps:
- Build-id: the scanner now reads the descriptor length from the note
header instead of assuming 20 bytes, so 8-byte ids from older
toolchains parse; the schema accepts 8-128 hex characters. Verified
against cone's readelf-reported ids on all three ABIs.
- Compiler line: the toolchain capture bound rises from 200 to 500
characters, keeping cone's 262-character clang line verbatim.
- Zero-byte libapp.so: the extraction target is created before streaming,
so an empty entry yields a clean unsupported_target refusal for
inspect_dart_aot and elf_header_valid: false with partial coverage for
identify_flutter_build, instead of a raw ENOENT with code UNKNOWN.
- Truncated library: identify_flutter_build marks fewer than two snapshot
sections as partial coverage with a limitation naming the count, and a
missing ELF magic gets its own limitation.
- Docs: the default ABI preference now matches the code exactly
(arm64-v8a, x86_64, x86, armeabi-v7a, then the rest alphabetically).
Also: every test that read the author's /tmp/opencode goldens now builds
a self-contained synthetic ELF64 image with dynsym, four snapshot
symbols, two snapshot sections, and a string pool, so the suite runs
anywhere; the verify lane now requires a present hex build-id per ABI
instead of accepting null.
* fix(flutter): address the Codex review findings
Eight findings, all applied:
- P1: SnapshotHashScanner keeps candidates in a Set (no quadratic
Array.includes) with a 64-distinct-hash cap, so a hostile payload of
magic+hash records cannot stall the scan or bloat the response.
- P1: projectStringPool stops admitting new distinct entries once each
category reaches twice its projection bound and reports
collectionCapped; allocation and sorting now track the response, not
the payload.
- P2: ZIP reader rejections during entry iteration or entry streaming
map into the typed error algebra (cancellation vs input refusal)
instead of escaping as unhandled exceptions in both operations.
- P2: magic_valid now marks coverage only for the *Data symbols; a
complete four-symbol image with valid data magics reports complete
coverage (the instruction symbols intentionally lack the magic).
- P2: the MCP server closes the Flutter provider during shutdown, so a
retained snapshot root is retried and reported, not leaked.
- P2: LabeledStringScanner commits matches only when a printable run is
delimiter-terminated; the carry grows to 600 bytes so a 500-character
toolchain line survives any chunk boundary untruncated.
- P2: both Flutter tool effects declare writesFilesystem: true; the
owned APK snapshot and extracted libapp.so are temporary writes.
- P2: the verify lane asserts every ABI agrees on exactly one snapshot
hash instead of discarding the computed set.
* fix(flutter): address the second Codex review round
Nine findings on the first-round fixes:
- P1: identify_flutter_build enforces a cumulative extraction budget
(768 MiB) across every library entry, not just per library, so an APK
with many ABIs cannot stream an unbounded total.
- P1: a single NUL-free printable run stops materializing at 1024 bytes
and marks the pool capped, so an adversarial one-run section cannot
allocate unbounded strings.
- P1: ELF cString bounds the NUL-terminator scan to the name maximum
plus one, so malformed symbol tables cannot scan the whole image per
entry.
- P2: mapReaderFailure distinguishes ArtifactReaderFailure texts —
budget/limit rejections map to resource constraints, integrity
failures (CRC/overlap/signature) to their own input refusal — instead
of collapsing all reader failures into one message.
- P2: the labeled-string carry is cleared when a delimiter commits a
run, so consecutive toolchain lines are never concatenated.
- P2: string-pool counts are renamed *_count_at_least and documented as
lower bounds, because capped collection discards values beyond twice
the projection bound.
- P2: inspect_dart_aot marks hash disagreements, non-pair source counts,
and candidate-cap saturation as partial coverage.
- P2: only valid lowercase-hex hash records count as snapshot sources;
complete magic records with non-hex fields do not inflate agreement.
- P2: the per-entry size refusal in inspect_dart_aot moves after ABI
selection, so an oversized unselected ABI no longer refuses a small
request.
* fix(flutter): address the third Codex review round
Five findings:
- P2: the owned snapshot revalidates the source after the copy (size,
mtime, inode), so an in-place replacement or swap mid-copy refuses
the observation instead of publishing mixed bytes.
- P2: a failed ZipArtifactReader close retains the snapshot root for
close() retry instead of silently swallowing the descriptor leak,
in both operations.
- P2: snapshot headers are parsed within their symbol bounds and a
symbol smaller than the 16-byte header reports magic_valid false,
so trailing-image bytes can no longer fake a valid data section.
- P2: the verify lane counts provider.close() cleanup failures as
lane failures instead of certifying a run with retained roots.
- P2: LabeledStringScanner reports toolchain_capped when further
distinct matching lines are observed past the 4-line projection;
identify marks such results partial with a naming limitation.
* fix(flutter): address rounds three and four of the Codex review
Round three (one missed finding) plus round four (five findings):
- P2: the GNU build-id note descriptor size is decoded from all four
bytes of the little-endian field, rejecting nonzero high bytes
instead of masking them to 16 bits.
- P1: the Flutter MCP handlers route through createContractToolHandler
and the session's analysisAdmission, so close_binary and snapshot
operations drain in-flight Flutter calls instead of racing them.
- P2: the owned-snapshot copy is a streamed, abort-checked write (no
copyFile), so cancellation stops the write promptly while the
source-identity revalidation (size, mtime, inode) still guards
against mid-copy replacement.
- P2: identify marks any snapshot_hash_sources value other than exactly
two as partial, matching the inspection path's pair requirement.
- P2: the verify lane refuses to run without --apk (exit 2) instead of
printing a false-green pass, and the engine check requires every
libapp-carrying ABI to have a present libflutter with a valid hex
build-id rather than filtering missing engines away vacuously.
* fix(flutter): address the fifth Codex review round
Six findings plus the upstream duplication baseline:
- P2: the flutter-provider kind reports available in the capability
inventory, so binary_session no longer lists always-registered
Flutter tools as provider_missing.
- P2: printable runs that exceed the 1024-byte cap are discarded at
their delimiter instead of emitting their truncated prefix as a
fabricated observation.
- P2: ELF symbols must fit inside the file-backed portion of their
PT_LOAD segment (p_filesz), so addresses in gaps or BSS are refused
instead of accepting unrelated bytes.
- P2: the build-id carry spans the complete 80-byte maximum note
(16-byte header + 64-byte descriptor) so chunk-boundary splits
cannot drop the first byte.
- P2: the labeled-string carry is sized for the toolchain pattern's
true 605-byte maximum, not the previous 600.
- P2: the AOT completeness predicate requires exactly two sources and
one candidate unconditionally, so zero-source images with valid data
magics report partial instead of complete.
Also: the shared ELF fixture builder and snapshot-section helper moved
to a dedicated FlutterTestFixtures module, eliminating cross-file test
duplication; jscpd now passes at 2.50% while main sits at 2.52%.
* fix(flutter): address the sixth Codex review round
Five findings:
- P2: snapshot-hash scanning is bounded to the exported data symbols'
byte ranges, so decoy or stale magic/hash sequences elsewhere in the
image cannot inflate source counts or contribute candidates.
- P2: labeled-string runs longer than the carry bound are rejected
instead of truncated, preventing a regex prefix from being published
as a verbatim source string.
- P2: the AOT image reread checks cancellation between file reads and
before the synchronous parsing stage, so a cancelled caller cannot
receive a success from a completed 256 MiB read.
- P2: the verify lane requires exactly two snapshot sources per ABI,
matching the provider's pair requirement, instead of accepting any
count >= 2.
- P2: ELF section and program header entry sizes are validated against
the class-defined minimum widths before walking either table, so
undersized entries cannot cause field reads to cross into
neighboring bytes.
* fix(flutter): address the seventh Codex review round
Six findings:
- P2: data-symbol ranges are deduplicated by offset and size, so aliased
symbols mapping to the same bytes are scanned once and the result
marks partial coverage with a limitation naming the shared range.
- P2: openEntrySafely forwards return/throw to the underlying Readable's
iterator, so an early for-await exit closes the ZIP entry stream and
releases its producer instead of leaking a backpressured pipe.
- P2: inspect_dart_aot now reports snapshot_hash_candidates and
snapshot_hash_sources alongside snapshot_hash, so a null hash from
conflicting evidence is distinguishable from missing hash data.
- P2: overlong printable runs only set toolchain_capped when they begin
with a recognized label prefix (Dart VM version: or Android (); other
long strings such as license text are skipped without marking partial.
- P2: readElfSymbol falls back to PT_DYNAMIC/DT_SYMTAB when section
headers are absent (e_shnum 0, ET_DYN), so stripped Flutter libraries
with exported snapshot symbols are no longer refused; the dynamic
table is bounded by DT_STRSZ, DT_SYMENT, and the image end.
- P2: the verify lane exercises inspect_dart_aot for every ABI carrying
libapp.so, not just the preferred default.
* fix(flutter): address the eighth Codex review round
Five findings:
- P2: each data-symbol range gets a fresh SnapshotHashScanner so the
carry from one noncontiguous slice cannot fabricate a record spanning
into the next; results are aggregated after scanning.
- P2: dynsym name lookups are bounded to the linked string table —
st_name offsets outside the table and terminators beyond it are
rejected instead of reading unrelated payload bytes as symbol names,
in both the section-header and PT_DYNAMIC paths.
- P2: identify_flutter_build routes its reader.entries and reader.open
calls through the same collectEntriesSafely and openEntrySafely
wrappers as inspect_dart_aot, so malformed ZIPs surface as input
refusals instead of AnalysisProtocolError.
- P2: mapReaderFailure recognizes ArtifactReaderFailure texts carrying
a cancelled reason, mapping them to AnalysisCancelledError instead
of AnalysisInputError.
- P2: the cumulative extraction cap is enforced inside the chunk loop,
not after each library completes, so refusal happens before the
remaining bytes are streamed and hashed.
* fix(flutter): harden streaming, sizes, and cancellation after self-review
Four issues found in a systematic self-audit across all bug classes
from eight Codex rounds:
- createReadStream in both the digest function and the owned-snapshot
copy now receives the AbortSignal directly, so cancellation aborts
the filesystem read at the source instead of waiting for the next
chunk to arrive on a slow filesystem.
- The owned snapshot enforces a 2 GiB APK-level size cap before any
copy I/O, so a path pointing at an enormous file is refused before
disk usage grows.
- identify_flutter_build preflights the sum of declared entry sizes
against the 768 MiB cumulative budget, refusing before any ZIP
extraction when the declared total already exceeds it.
- The LabeledStringScanner triple result() call is collapsed to a
single invocation (the previous code called result() three times in
the emission, relying on end() being idempotent).
No behavior change for valid inputs; all 36 tests, check:fast, and
the cone verify lane pass unchanged.
* fix(flutter): require structurally parseable ELF headers for complete coverage
CassieFox23's third corrupt-header case: an ELF with valid magic but
zeroed section/program header offsets passes the 4-byte magic check
and the byte scanner still finds hash patterns in the data sections,
so identify_flutter_build reports complete coverage for a structurally
broken file.
The elf_header_valid check now also verifies beyond the magic:
e_type must be a known value (ET_REL/ET_EXEC/ET_DYN), at least one
of e_shoff/e_phoff must be non-zero, and at least one of
e_shnum/e_phnum must be non-zero. A file with valid magic but zeroed
structure reports partial coverage with the existing ELF-magic
limitation.
* fix(flutter): validate ELF and snapshot coverage
Share bounded ELF header parsing between identification and inspection. Accumulate headers across ZIP chunks and validate table entry widths and extents before claiming complete identification coverage.
Bind AOT hashes to the exported VM and isolate headers, validate stored snapshot lengths including the magic bytes, and preserve partial evidence for missing, malformed, aliased, or overlapping data headers.
Preserve native stream cancellations and APK resource constraints across both operations. Bound snapshot copies while streaming and retain useful input-failure diagnostics and lower-bound count wording.
Validation: 72 focused tests; check:fast; check including formatting; docs:check; test discovery; jscpd; real cone APK and non-Flutter control on Linux. Verified CLI/MCP parity for valid and corrupted ELF headers and AOT inspection across three ABIs. Native Windows and macOS were not run.
* fix(flutter): unify artifact ownership and bound ELF evidence
* fix(flutter): preserve ELF provenance and partial coverage
Read GNU build IDs only from bounded ELF note ranges and retain conflicting candidates. Preserve source versus owned storage failures and honor cancellation through parsing and final cleanup.
Separate snapshot structure from string-pool coverage. Verify every Gallery ABI with digest-bound engine labels and URI counts, and document the supported snapshot-kind layout.
---------
Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
createCli parsed REA_LOG_LEVEL with a throwing schema, so an invalid or
uppercase value crashed every command, including doctor and --help, with
a ZodError stack trace. Parse it into a ConfigurationError result and have
the executable print the same configuration message as the MCP adapter
and exit 1 before building the CLI.
Fixes#2135
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: narrow native-host lane selection and reuse build caches
Unowned src/ and bridge/ files no longer fall back to the full baseline.
They run the Linux suite plus the Linux x64 installed-package/Inspector
baseline. New apple and package scopes own the Apple artifact lane, the
package matrix and the Windows curated lane, including the test files those
lanes invoke. Manual-only verifier entrypoints run static checks and the
Linux suite. CHANGELOG, SECURITY, GitHub templates and the native Windows
README are documentation-only.
Pull requests omit the macOS x64 package host unless labelled ci:full.
The Windows and Apple lanes restore the shared Turbo build cache, the
Windows lane drops its duplicate typecheck, and the Linux suite uses six
shards. Main pushes keep the full baseline.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: match package script entrypoints against scope globs
Script-only package.json edits resolved their entrypoint with literal
equality, so glob-owned verifiers such as scripts/verify/apple/** and
scripts/verify/inspector/** fell back to the full baseline instead of
selecting their owning lane.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Exercise cold and warm completion through ordinary provider operations. Bind fixture observations to the selected analysis profile so the warm-up call satisfies session validation, and make package completion candidates explicit with useful failure diagnostics.
07b36c148 made document and procedure completion read only from an
already-started provider client. Two checks still completed right after
opening a target, so they observed an empty cold result:
- promptCompletion.test.ts used a fixture client without executeIfReady
and never ran an ordinary operation, so the composite provider had not
created a client yet.
- The packaged MCP smoke expected live completions on non-Linux hosts
immediately after open_binary, before current_document started Hopper.
Both now assert the cold result is empty, ready the provider through an
ordinary operation, and then assert the unchanged live candidates.
Fixes#2123
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Label new captured response bytes as Playwright body API results and retain the possibility of a credentialed follow-up load. Preserve legacy representations and source limitations through export without treating body-origin uncertainty as missing event coverage.
Validated source and filesystem boundary tests plus real Chrome CLI and MCP network workflows covering binary, compressed, empty, unfinished, and same-URL responses and profile cleanup.
* fix(scripts): defer dist/ imports in verifier helpers so test:fast runs without build
Two helpers under scripts/lib/ reached into ../../dist/ at module load even
though the top-level import was only needed by one of their exports. That
turned mocked, dist-free tests into failing tests under `npm run test:fast`,
which docs/testing.md § test scripts explicitly promises runs "without build":
- tests/conformance/providers/hopper/realHopperSemantic.test.ts only calls
requireCurrentDocument and resolveFixtureProcedure (both mock-only), but
scripts/lib/real-hopper-semantic.mjs eagerly imported
requireFunctionDossierOracle from dist/application/RealHopperAssertions.js.
Moved the dist-dependent dossier oracle into a lazy loader called from
verifyRealHopperFixture, which is where it is actually used (against the
real Hopper bridge, after build:cached).
- tests/evaluation/package/packagePlatformDiagnostics.test.ts only uses
assertLinuxPackageProviderFailure, which depends on `json`, but
scripts/lib/verify-package-core.mjs eagerly re-exported helpers from
mcp-verifier-results.mjs, which in turn pulls four dist/ modules. Moved
that import into verifyCompleteToolCatalog (the only consumer in this
file). Downstream scripts (verify-recorded-crash.mjs, verify-package-mcp.mjs,
verify-windows-package.mjs) are unaffected because they already run after
build:cached.
Reproduction before fix:
rm -rf dist && npm run test:fast → 2 failed (both import-time errors)
Reproduction after fix:
rm -rf dist && npm run test:fast → 388 passed, 4924 tests, 0 failed
npm run build:cached && npm run test:fast → 388 passed, 4924 tests, 0 failed
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(install): orient Node.js version mismatch failures with actionable remediation
install.sh previously told operators "use Node.js 22.x (>=22.19), 24.x (>=24.11),
or 26+" without saying how to install one. The curl|bash onboarding path then
left the operator to guess between nvm, fnm, n, Volta, system packages, or
nodejs.org — a lookup that bounces across search engines for a first-time user.
Replace the one-line failure with a block that:
- Names the detected Node.js version (so the operator confirms it is theirs).
- Shows the three most common install paths (nvm, fnm, direct tarball).
- Pins the Node.js release line (24) that satisfies the engine, so copy-paste
commands produce a supported runtime instead of whichever "latest" is on top.
- Maps uname -m / uname -s to the Node.js tarball label pair for this host
(e.g. darwin/arm64, linux/x64), so the operator can grab the right archive
from https://nodejs.org/dist/latest-v24.x/ without a second lookup.
Verified with four Node.js versions (24.18 compatible, 25.9/20.11 outside the
supported ranges, 22.18 below the minor floor) that remediation triggers only
on real mismatches and names the host labels correctly. shellcheck install.sh
and npm run check:fast remain clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Keep omitted discovery attachment state as null through Node, browser, Electron, and reconciliation evidence. Report the uncertainty while retaining Node observation unless discovery explicitly marks the target attached. Reject worker TargetInfo records missing the required boolean with partial coverage.
Validate omitted and explicit states through provider, CLI, and MCP boundaries and real Node 24 Inspector workflows. Consolidate Electron regression coverage into the existing list-and-inspect workflow.
BREAKING CHANGE: attached fields in JavaScript runtime, browser, and Electron target discovery and inspection results may be null when discovery does not report attachment state.
* feat(go): inspect embedded binary build metadata
* fix(go): preserve byte metadata and validate container mappings
* fix(go): support moduleless legacy build metadata
Recognize optional module string headers in declared zero-filled memory while rejecting ambiguous and unmapped pointers. Preserve the original module-pointer field as the zero-byte source anchor.
Classify initial symlink-loop and overlong-path failures as invalid input, with CLI and MCP regressions.
* fix(go): reject undersized PE optional headers
* fix(native): stabilize ELF memory checks and clean up exec wrappers
Use existing parent/group/run-token ownership for caller-selected Python launchers, which can exec through a shell or prlimit. Add cancellation regressions for the valid wrapper and wrong-parent/token cases.
Replace the timing-dependent 30,000-section memory workload with a valid 32 MiB padded ELF under a 64 MiB address-space limit. Check the same image successfully through CLI and MCP before requiring a typed memory failure, preserving the production timeout and all error assertions.
Validation: npm run check and check:fast passed; 61 focused tests passed including Go CLI/MCP and session snapshots. Real decoder probes with pinned packages passed on Python 3.12.3 and 3.12.14. The full local ELF verifier is blocked by this container's procps/process-ownership boundary; the exact pushed head requires GitHub's real-binary-layout lane.
* test: repair Electron fixtures and stabilize catalog startup checks
Declare Electron imports in option, preload override, and path-resolution fixtures after upstream began requiring proven API provenance. Retain all option and preload assertions and adjust exact source ranges for the added import line.
Use the existing bounded acceptance timeout for the cold catalog lifecycle test instead of a separate 15-second ceiling. This retains the coverage allowance and all catalog, error, and cleanup assertions without retries.
Validation: npm run check, final check:fast, formatting and diff checks passed. Source path regression and Go boundary/MCP/service checks passed. All 20 Go CLI cases and both supported-host runtime cases passed on rerun; two macOS-only cases skipped on Linux. A prior contended local run timed out once in a Go CLI diagnostic; that case passed on rerun. Electron process-boundary verification is blocked locally by procps namespace inspection and requires fresh CI.
* test(mcp): isolate nested schema references between tool contracts
Clear Ajv's non-meta schema registry after each root, including compilation failures. Disabling root registration alone leaves nested IDs available to later tools and can let a dangling reference pass the catalog gate.
Add regressions for leakage after successful and failed compilation while retaining shared meta-schema validators. The regression failed before the fix; all 11 schema cases and full npm run check pass. Reviewed independently.
* test(ci): align Go effects and source-map verification contracts
Audit the Go inspector wording as static metadata inspection. Assert retained source declaration indexes in BOM reconstruction and the compiler-derived nested-map oracle. Keep a 45,000-map admission control below the 32 MiB output budget and the 50,000-map overflow case above it with the expanded representation.
Validation: reproduced all four failing assertions, then passed 120 focused tests and the final admission suite. npm run check and real Chrome 154 / esbuild 0.25.10 source-map verification passed, including all four nested-map scenarios and verified process lineage.
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Replace stale closed-property expectations with assertions for the evidence under test. Verify compiler coordinates and declaration indices separately in the real-browser workflow.
Consolidate duplicate 50000-map admission cases and derive admission from exact serialized bytes rather than IP-address-specific output shapes. Retain capacity, omission, and aggregate-byte coverage. A bounded Flameox CPU profile completed in about 1.4 seconds and showed no producer bottleneck; targeted admission and real Chrome CLI/MCP verification pass.
* feat(setup): register DeepSeek Harness through setup, doctor and uninstall
DeepSeek Harness registers MCP clients through a Cordis YAML patch
sequence in the home patch rather than a server table, so setup could
not configure it and users had to append the documented entry by hand.
Add a dsh client: the home patch $DSH_HOME/cordis.patch.yml
(~/.dsh/cordis.patch.yml when unset) is parsed as a patch list, the REA
entry owns the stable rea-mcp id, and setup appends or replaces exactly
that entry while preserving unrelated patches and comments in place.
Doctor reports the registration through the same entry, and uninstall
removes it, dropping insert operations it emptied. Skill destinations
follow ~/.agents/skills ($DSH_AGENTS_HOME/skills when configured), the
home the rest of the client machinery already uses.
Fixes#1839
* fix(setup): carry environment and identity validation into DSH registrations
Address review: the DSH entry discarded discovered provider overrides;
config.env is now emitted and retained like the other dialects. An entry
carrying the rea-mcp id under a wrong or missing package name, or
duplicated entries, reads back as absent so setup rewrites exactly one
canonical entry instead of reporting unchanged. Doctor now requires
serverName rea and stdio transport before calling a DSH registration
aligned, and the Harness skill identifier in the docs matches the
installed reverse-engineer-anything skill.
* fix(setup): apply Cordis patch order and collapse DSH registrations
Address review: a later direct { id, config } operation replaces the
row's config under the native patch DSL, so the registration view now
applies patches in order instead of only reading insert operations;
doctor reports the effective command rather than the inserted one.
Setup rewrites exactly one canonical entry: duplicate id-matching rows
collapse to the first, direct patches to the entry are dropped from the
document and from the edited YAML, and uninstall removes them with the
entry. The client-location test fixture now clears DSH_HOME and
DSH_AGENTS_HOME so a developer environment cannot point the suite at
real Harness homes.
* fix(setup): repair direct-only registrations and preserve Cordis entry state
Serialize now edits the first insertion carrying rea-mcp in place, so a
grouped entry keeps its scope, neighbors, and comments instead of moving
to a fresh root-level insertion, and later carrying insertions and direct
patches collapse away. Entry-level disabled state projects into the
registration the doctor and setup compare, so a disabled row reads as
stale and the repair re-enables it. A direct-only registration no longer
suppresses the canonical insert append, and an update retains the
registration environment. Duplicate entries collapse across operations,
not only within one.
* fix(setup): preserve Harness row state through identity and refresh repairs
A wrong-package row still reads back as a server record carrying its
environment and caller fields, projected with a package marker the
alignment path treats as stale, instead of vanishing and dropping
config.env from the repair. A direct Cordis patch without a preceding
insertion configures nothing, so a direct-only registration reads as
absent even when its config matches and the repair appends the insert.
Caller-owned config fields beyond the REA-owned keys, such as the cwd
the native verifier sets, survive a refresh instead of being silently
dropped.
* fix(setup): preserve Cordis tags and collapse aligned Harness rows
A refresh rebuilt Harness config from parsed values, so a caller !!js
expression was written back as a literal. Owned keys are now overlaid on
the winning config node and other nodes stay in place. Two already-aligned
rea-mcp insertions read as stale, so setup collapses them to one row, and
the bundled skill lists dsh with the other clients.
* fix(setup): drop the unused DSH configuration type
Knip reports DshConfigurationFormat as an unused export. The format union
does not depend on that alias.
* fix(setup): keep Harness env tags and comment-only patches
A refresh replaced the whole env map, so a caller !!js value was written
back as a literal. Environment entries now stay in place unless the value
changed. A comment-only cordis.patch.yml parses as an empty patch list and
keeps those comments when the registration is appended. Docs describe
plain rea uninstall, which scans supported clients and has no --client flag.
* fix(setup): own Harness rows by entry id and expression state
Uninstall removes a rea-mcp row even when the launcher is stale or the
patch never established a server record. A non-boolean disabled value,
including a Cordis expression, reads as stale. Expression text on a known
environment setting is not validated as a literal path, so a refresh can
keep the tag.
* fix(setup): collapse aliased Harness insertions
An anchored insert followed by an alias parses as two rea-mcp rows, but
the YAML edit kept the alias, so readback stayed duplicated and setup
restored the file. Aliases that resolve to the owned entry are now
dropped, including an alias of the entry inside one insert. Aliases of
other patches stay.
* fix(setup): resolve aliased Harness lists and config maps
An insert value that aliases another entry list still loaded a second
rea-mcp row after the operation-level alias collapse. That alias is now
dropped once the anchored list is rewritten. A config: *cfg map is
resolved and cloned before the refresh, so a caller !!js field on the
aliased map is not rewritten as a plain literal.
* fix(setup): follow Harness aliases for ids, lists, and env tags
An insert alias whose anchor is not another insert is copied so
unrelated rows stay while the owned row is rewritten. An aliased
entry id is resolved before ownership checks, and an environment alias
of an unchanged !!js scalar is left in place.
* fix(setup): keep aliased Harness env maps through uninstall
An env alias is cloned before a refresh so tagged values are not rebuilt
as literals, and expression-key scans follow aliases before path checks.
Insert aliases that carry REA are recorded before uninstall empties their
anchor, so the later alias is dropped instead of dangling.
* fix(setup): follow root Harness aliases and mark dsh as main-only
Winning-config walks resolve a root alias before patch order, so a replayed direct config's !!js env is not validated as a literal path. Root aliases that own rea-mcp are recorded before uninstall empties their anchor. An insert whose only owned member is an external alias is cloned so Cordis tags survive. Docs state dsh is not in npm 6.4.0.
* fix(setup): keep rows behind inert Harness aliases
A root alias whose anchor is not a loaded operation is copied and only the owned row is edited, so unrelated rows stay active. Entry id aliases become a scalar before their anchor patch is dropped. Root-alias ownership follows insert-list aliases, so a replay is removed instead of dangling after uninstall.
* refactor(setup): centralize Cordis source ownership
* fix(javascript): share Electron mutation proof with wrapped calls
* test(mcp): align graph and catalog checks with current contracts
* fix(setup): separate Cordis ownership from editability
* docs: clarify ownership and interpretation boundaries
* fix(setup): preserve Cordis applicability and caller metadata
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* test(clients): verify native Gemini CLI integration on Windows
The Gemini CLI client lane asserted POSIX. On Windows it also needs the npm install's JavaScript entry point, because only a gemini.cmd shim reaches PATH, and two setup-plan checks compared paths with a hard-coded slash. Remove the assertion, run a selected .js, .mjs or .cjs entry point under the verifier's Node, build those prefixes with path.sep, name the entry point in the Windows preflight error, and record 0.63.0 as verified on native Windows in docs/testing.md.
Fixes#1935
* test(clients): resolve the selected Gemini CLI entry point once
The preflight runs from the caller's directory and the client run from the disposable workspace, so a relative REA_VERIFY_GEMINI_COMMAND passed the preflight and then failed with Cannot find module. Resolve a selected JavaScript entry point to an absolute path before both launches.
* feat(mcp): derive an API surface view from retained web network captures
* fix(mcp): fail closed on sensitive parents and budget api-surface path expansion
* fix(mcp): keep recorded api-surface paths and budget only templated segments
* fix(mcp): read api-surface paths only from canonical URLs and charge new values once
* fix(mcp): reject authority-less api-surface URLs and key groups by rule positions
* fix(mcp): label api-surface confidence from all groups and cap transient path memory
* fix(mcp): budget api-surface dedup sets and narrow detail outputs
Charge retained deduplication sets before allocation, advertise only
each analysis operation's summary from its detail output, and document
that any templated group makes every API-surface page inferred.
* fix(mcp): bound api-surface path text and record limitations
Charge retained literal path copies before allocation, publish only
valid media-type essences, and deduplicate examined record limitations
onto the view.
* fix(mcp): keep api-surface refusals and path splits inside the reply budget
Sensitive-parent refusals now use the token sensitive_values_unretained so declared literals are not echoed. A later path split is charged against bytes already retained, and the published example includes the HAR record limitation with its matching digest.
* fix(mcp): budget api-surface method text before group keys
Charge method and origin text against the reply budget before the group key is serialized. Document that samples merge only when method, origin, and exact segment rules match.
* fix(mcp): bound api-surface copies and control-character authorities
Reject authorities containing a tab or newline so WHATWG cannot move userinfo into the recorded path. Charge four path copies, two method and origin copies, and each distinct content type against bytes already retained.
* fix(mcp): preflight combined api-surface group charges
Total path, method, origin, and segment charges before retaining a new group. Track content types in a set so distinct MIME essences are not compared quadratically.
* fix(mcp): charge api-surface content-type sets on first use
Create the per-group content-type set when the first essence is retained, and charge it before allocation. Groups with no content type no longer keep an empty set.
* refactor(analysis): centralize API-surface ownership and admission
Own grouping, deduplication, and combined retained/temporary resource admission in one accumulator. Charge fixed group storage before allocation and materialize only the requested page.
Share recorded URL parsing between capture redaction and projection, preserving source paths and excluding ambiguous credential fields. Cover resource admission invariants and the compiled HAR-to-view workflow.
* fix(analysis): admit capture schema clone before parsing
* fix(javascript): share Electron mutation proof with wrapped calls
* test(mcp): align graph and catalog checks with current contracts
* fix(analysis): admit and validate portable capture views
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Return deduplicated execution caveats once and preserve provider-owned relationship diagnostics and completeness on graph nodes. Keep complete relationship reads exhaustive despite contextual caveats, including portable call-path reconstruction.
Preserve omitted diagnostic fields in historical Evidence and bind reported diagnostics into semantic identity. Revise graph workflow and Ghidra adapter profiles so old cached representations cannot replay under the new contracts.
Remove stale duplicate-lookup test claims and redundant fixture validation. Prune million-entry duplicate cases while retaining argument-stack and deep-chain regressions; bounded Flameox captures identified validation and canonical hashing costs.
Validation: static and architecture checks, generated docs, 364 focused tests before pruning, 21 call-path tests after pruning, public MCP schema validation and targeted profile tests. Real engine behavior was not locally exercised.
BREAKING CHANGE: get_call_graph normalized_result now contains { graph, limitations }; traversal-depth groups are under graph.
Bundle ordinary CLI and output entries to reduce Windows module filesystem resolution while preserving source URLs, lazy loading and worker resources. Keep release identity in its shared owning module.
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* test(ghidra): require pending multi-HI16 coverage in the real MIPS relocatable lane
Post-merge review on #1950: the relocation oracle exposes coverage.multiple_hi16, but the real-Ghidra lane never required it, and Clang's C output never produces a LO16 that resolves several pending HI16s. Ghidra's loader could therefore mishandle that stream while the lane still passed, although most GCC-built kernel modules checked contain it.
The relocatable fixture adds an assembly block with two lui %hi(rea_mips_rel_carry); LLVM's relocation sort then leaves one HI16 pending until a later LO16 that resolves it together with another HI16, including the carry. The lane now requires multiple_hi16: false on the previous fixture, true for all three variants (LE, BE, soft-float module) on real Ghidra 12.1.4.
* test(ghidra): make the MIPS multi-HI16 fixture independent of relocation sorting
Review on #1974: the block used two %lo of rea_mips_rel_carry, a symbol with other %lo uses, so the relocation stream depended on the assembler's HI16/LO16 sort. Clang 21 happened to leave a HI16 pending; Clang 17 (per review) and GNU as 2.45 (checked here: HI@4 LO@8 HI@0 LO@10) pair each HI16 with its own LO16, so multiple_hi16 stays false and the lane fails.
Use a dedicated symbol with two %hi and exactly one %lo. Any assembler that orders each HI16 before a matching LO16 must then emit both HI16s ahead of that single LO16: Clang 21 gives HI@0 HI@4 LO@8, GNU as 2.45 gives HI@4 HI@0 LO@8. The real-Ghidra lane passes for LE, BE and the soft-float module variant with multiple_hi16 true.