mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
e6d0618979f0df3f1d5db218b0fc7b5e6a9cf3f9
71
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e6d0618979 |
feat(artifacts): inventory and extract ESP flash layouts (#8228)
* feat(artifacts): inventory and extract ESP32 firmware images ESP32-family app and bootloader images (magic 0xE9) had no reader, so open_binary refused OTA downloads, app partitions and bootloaders. Add the esp-image container format behind inspect_artifact and extract_artifact. A pure decoder reads each byte once and keeps only fixed-size fields. Derived facts cover the chip, from a table cited to ESP-IDF v6.1; segment classification as ESP-IDF's should_map and should_load; checksum and appended SHA-256 results; app and bootloader descriptors; Secure Boot v2 signature blocks, observed and unverified; and undescribed trailing byte ranges. Truncation and undescribed bytes make coverage unknown. ESP8266 images are refused with a specific reason, and ciphertext stays unrecognized. Add the format to every target, Evidence, snapshot, live-summary and artifact vocabulary, document it, and add an optional verify:esp-images lane that compares esptool-built images with esptool image-info and espsecure signature-info-v2. Refs #3615 * test(artifacts): run the ESP image lane on esptool v5.6.0 The lane compared descriptor fields only when esptool image-info printed one, so a descriptor that REA reports and esptool does not print passed without comparison. Compare the descriptor kind in both directions. Record that the lane passed for all 13 images with esptool and espsecure v5.6.0, the version the layout facts cite, as well as with 4.12.0. * refactor(artifacts): define ESP image layout sizes once The decoder and the derived facts each defined the segment-header, appended-digest and flash-sector sizes, the erased-byte scan and the offset formatter. Define them once with the other fixed-layout structures and import them in both places. The signature slot count is the one constant that drives the slot scan. Correct the observedEnd comment: it is the end of the last chunk read. * fix(artifacts): report ESP-IDF's segment length limit by chip ESP-IDF's verify_segment_header rejects a segment of 16 MiB or more unless the chip maps flash through 32-bit cache addresses (SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP: ESP32-S3, P4, C5, C61, H4 and S31 in v6.1). Record that capability in the chip table and add a limitation for such segments; unknown chips get none. `loaded` repeats should_load. It does not mean the bootloader accepts the segment: verify_load_addresses still rejects one outside the chip's RAM, which REA does not model. Say so in the docs, the skill reference and the inventory limitation. * test(artifacts): check ESP lane tools first and verify extraction The lane started work before checking its tools, so a missing RISC-V target, ld.lld, esptool or espsecure surfaced as a raw spawn or command error. Check each one before building and name the variable to set. Warn when esptool is not v5.6.0, the release the layout facts cite. Assert each segment's class for the ESP32-C3 app, its variants and the bootloader, as the Xtensa image already did. Extract the app and the signed image through the CLI and compare every file with the bytes at esptool's segment offsets or in the appended signature sector; the source's SHA-256 must be unchanged and equal the reported root_sha256. * docs(artifacts): state what the ESP image lane does not establish The Verification section listed the lane's checks but not its gaps: only ESP32-C3 and ESP32 images come from a real producer, no real project build, OTA download or flash dump is inspected, no signature is verified, and the lane does not run in CI. Record the timing of the final lane run on esptool v5.6.0. * fix(artifacts): compare ESP segment declarations Segment entries hash only their data, so compare_artifacts reported a segment that moved to another load address with the same bytes as unchanged; only the image itself changed. Compare each segment's load_addr and data_len as its declaration, as Node SEA and PyInstaller members are compared, and count a changed declaration as a metadata change, also when content is unavailable. Header offsets are layout and the classification is derived, so neither is compared. * test(artifacts): run ESP lane commands as owned process trees The lane ran its tools through execFile. A timeout killed only the direct child, so a linker or assembler that Clang or GCC had started could keep running while the lane removed its workspace. Run every command through createVerifierCommands, check the tools inside withVerifierCleanup, and remove the workspace only after commands.close() has stopped every tree; a failed close keeps the workspace. Only a nonzero exit now counts as a refusal or an expected esptool failure; timeouts and spawn failures propagate. Supervising each command roughly doubles the lane's run time. * test(artifacts): cancel ESP decoding after its first decoded chunk The cancellation test requested cancel or close on setImmediate, which can land while the file is still being opened and checked, so it never showed that decoding had started. It also passed against a reader that ignored both requests while decoding. Acknowledge the decoder's first chunk, then cancel or close, join the operation, and assert that no later chunk reaches the decoder and that the reader ends closed. * docs(artifacts): record which ESP metadata comparison ignores Segments are compared by their declaration. The image's and the signature blocks' format_metadata are not: every field comes from their own bytes, which content comparison already covers, and a block's image_digest_matches follows the image's content. * feat(artifacts): inventory and extract ESP flash layouts A whole-flash dump of an ESP32-family chip was read as its bootloader image, with the partition table, apps and data left as undescribed bytes, or refused when it began with erased flash. Read it as an esp-flash-image container instead. The partition table is decoded as esp_partition_table_verify accepts it and is found at the caller's partition_table_offset, at the default 0x8000, or by scanning 0x1000-aligned sectors for a table whose MD5 verifies, which the inventory reports as derived. The bootloader is located at its chip's ROM bootloader offset. Each partition is an entry with its declaration in flat format_metadata; the bootloader and app partitions carry ESP image facts from the existing streaming decoder; the otadata records are reported with a selection derived without rollback or anti-rollback, and the running partition stays unknown. One unreadable partition does not hide the others, and extraction writes every partition, nvs_keys included, as ordinary data. Flash layouts are detected before single ESP images. The scan runs only when an ESP image sits at a ROM bootloader offset, and is refused when a bootloader at another chip's offset shows that the dump does not start at flash address 0. open_binary gains flash_offset and partition_table_offset, which require format esp-flash-image and are part of the snapshot target identity; the CLI takes them with --target-format esp-flash-image. Comparison treats a partition's label, type, subtype, range and flags as its declaration. * test(artifacts): verify ESP flash layouts with gen_esp32part, merge-bin and otatool Add the optional verify:esp-flash lane. It builds default and relocated partition tables with ESP-IDF's gen_esp32part.py, assembles dumps with esptool merge-bin, including one written from flash 0x1000, and writes OTA records with otatool through flash_file_tool.py, which replaces parttool's esptool calls with reads and writes of the dump file. It compares REA's bootloader and app facts with esptool image-info, every partition with gen_esp32part.py's decoding of the extracted table, and the OTA records and derived slot with otatool read_otadata after each switch. It also checks extracted bytes and source integrity, the scan and caller table offsets, flash_offset on the 0x1000 dump, a corrupted app beside valid partitions and a truncated dump. ESP32 linker scripts place the conformance bootloader and app in ESP32 address ranges. * fix(artifacts): read ESP flash layouts as the bootloader does Read the partition table as bootloader_utility_load_partition_table does: the last factory, otadata and same-subtype OTA declaration wins, and a limitation names repeats. Plan each otadata record within its partition and the dump. An otadata partition smaller than two sectors selects none, the bootloader's INVALID_INDEX; a record the dump lacks leaves the selection unknown while the other record stays reported. The fallbacks follow the bootloader's indexes: ota_0-fallback and factory-fallback name no partition when the table declares none, and the assumptions add GPIO holds and deep-sleep wake. Refuse a dump whose bootloader contradicts its origin before the default table offset is tried, whether flash_offset was omitted or given, and keep the ESP image reader's ESP8266 refusal. A table never lies inside the located bootloader image, so single app images are no longer scanned. An explicit esp-flash-image selection is decided before other container signatures, and the native commands' --target-format no longer takes it. Say when no bootloader confirms the default origin. Exempt the primary bootloader and partition_table entries of ESP-IDF 5.3 from placement limits, report every region inside a longer one, and name partitions by index when labels repeat ignoring case. Keep an undecodable label's bytes in label_hex and compare them. Word undescribed ranges as starting at a byte that is not erased, and treat a short erased region as erased. Add an MCP compare_artifacts test for partition declarations, reader identity and close tests, scan edge cases, the 0x2000 ROM offset and a literal otatool CRC. * test(artifacts): verify ESP primary layout entries and the otadata fallback Build a table with the primary bootloader and partition_table entries that gen_esp32part.py fills from --primary-bootloader-offset, and check that REA reads it with complete coverage, no overlap or misplacement limitation, and a table that agrees with gen_esp32part's decoding. Erase the otadata with otatool after the slot switches and check the records against read_otadata and the factory fallback. * fix(artifacts): keep ESP flash coverage complete for a dump cut short An esptool merge-bin dump ends after the last part it wrote, usually inside its last partition. Such a partition made the layout's coverage unknown, so artifact comparison of two merge-bin dumps reported every unchanged partition as unknown. The partition table names every partition whatever the file's length, so a partition cut short or left out by the end of the file hides no entry. As the ESP image reader does for a cut-short segment, its entry holds the bytes the file has and an entry limitation gives the declared size; a partition with no bytes stays in partitions_outside_dump. Coverage stays complete unless undescribed bytes remain or no bootloader is located. An MCP compare_artifacts test of two dumps that end inside ota_0 now classifies every partition, and fails on the old rule. * fix(artifacts): report written bytes in ESP partitions, erased slots included An app slot is erased for ESP-IDF's bootloader when its image header bytes are erased flash, and REA reported only that status. A slot can still hold data further in: a dump read from a device held a complete older app image 1 MiB into an OTA slot reported as erased, with no limitation. Each partition entry now records where the bytes the dump holds are written, relative to the partition: written_offset, the first byte that is not 0xFF, written_end, just past the last, and written_bytes, how many are not 0xFF. They are null for a partition outside the dump. The status stays erased, which is the bootloader's view, and a limitation names an erased app slot that holds written bytes and says they are not read as an image. The reader reads every partition byte once more to find them. * fix(artifacts): derive the ESP boot selection for every partition table The boot selection lived inside otadata, so a table without an otadata partition, the common factory-only layout, had none. ESP-IDF's bootloader_utility_get_selected_boot_partition returns the factory index when the table declares no otadata partition. Move it to a top-level boot_selection that every layout has. Its basis names the bootloader's branch: otadata, factory-fallback and ota_0-fallback from the records, no-otadata for a table without otadata, none for the bootloader's INVALID_INDEX, and unknown when the dump lacks a record the bootloader reads, which replaces the null selection. running_partition moves with it, and otadata keeps its partition index and records. The assumptions name what each branch leaves out: no records assumption without otadata, and none for none or unknown. The real-tool lane checks no-otadata on a table gen_esp32part built without otadata. * fix(artifacts): say when an ESP image is a flash dump read from 0x1000 An ESP32 dump read from flash 0x1000, as read-flash 0x1000 or merge-bin --target-offset 0x1000 writes it, opened automatically as its bootloader image with a megabyte of undescribed bytes and no next probe. The flash reader refuses that origin, but nothing told an agent which flash_offset to pass. espFlashDumpOrigin owns the inference: an image of a chip whose ROM loads the bootloader from flash R, at file offset F, is the bootloader of a dump read from R - F when a partition table sits where that origin puts 0x8000. The ESP image reader asks it for a non-app image at file offset 0, so the result does not depend on how the reader was created, and records flash_dump {flash_offset, table_file_offset}, null otherwise, with a limitation that says to reopen the file as esp-flash-image with that flash_offset. inspect_artifact proposes the same open_binary call as a next probe, and the flash reader's misplaced-origin refusal names the offset. * perf(artifacts): summarize nested ESP images in the flash layout summary view The summary view returned an ESP flash layout's root facts whole, so each app partition and the bootloader carried every segment and signature block, about half of a dump's summary. The summary view now gives each nested image a summary instead of its facts: status, chip, entry point, segment count, load ranges (each mapped, loaded or unclassified segment's address and declared length), the checksum and appended SHA-256 statuses, coverage and limitations. Complete detail keeps the full facts, every segment included, and the retained Evidence is unchanged. On a 16 MiB device dump the summary's root falls from 5,141 to 2,657 bytes, and the summary Evidence from 10,038 to 7,554. * test(artifacts): expect the misplaced image the ESP bootloader search reports |
||
|
|
37342ecde0 |
feat(native): open extension, framework, XPC and plug-in bundle directories (#8117)
* feat(native): open extension, framework, XPC and plug-in bundle directories open_binary and the CLI inspection commands admitted only .app directories and pointed every other Apple bundle at the JavaScript analyzer. Resolve .appex, .framework, .xpc, .systemextension, .bundle and .plugin directories through their Info.plist CFBundleExecutable, in the Contents or flat root layout, plus the versioned framework layout under Versions/Current. Exactly one layout may declare the bundle and every resolved path must stay inside it. Unresolvable bundles fail closed with typed constraints, probed paths and the Info.plist that was read. Other Apple bundle types are refused as unsupported instead of being offered the JavaScript route. Resource-root discovery shares the same layout rule, so inspect_plist reads a versioned framework's Info.plist. The recognized bundle vocabulary now has one owner in the domain. Refs #4310 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(native): refuse kernel extensions and state bundle error fields Name the Apple bundle types binary routes recognize but do not open (.dext, .kext, .qlgenerator, .mdimporter) explicitly, so a kernel extension is refused as unsupported instead of receiving the JavaScript route. Document which bundle refusals carry probed_paths and info_plist, and make success tests throw the typed admission error before asserting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(native): open flattened frameworks through Resources/Info.plist Electron and Gecko apps ship frameworks without Versions/: the program file sits at the framework root beside Resources/Info.plist, the layout #8101 taught bundle anatomy. Read that layout for a framework without Versions/, and keep the versioned layout for one with it, so a versioned framework's root Resources link is never read as a second declaration. The resource root reports it as flattened-framework. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d39b3000ec |
feat(artifacts): inventory and extract U-Boot FIT images (#7771)
* feat(artifacts): inventory and extract U-Boot FIT images open_binary refused U-Boot Flattened Image Tree files as an unsupported format, so inspect_artifact and extract_artifact could not list or recover a FIT's kernel, devicetree, ramdisk and loadable images. Recognize an FDT v16/v17 with a top-level /images node and parse it with the existing parseDevicetree. Each /images child becomes an inventory entry named images/<unit-name>.bin that extracts its stored bytes from embedded data, data-offset (past the 4-aligned devicetree end) or data-position (from the file start). Image format_metadata records the declared type, arch, os, compression, load and entry; root metadata records the description, timestamp and configurations. crc32, md5, sha1, sha256, sha384 and sha512 hash nodes are verified in one streamed pass per image; other algorithms are reported unverified. Signatures are reported, not verified, and nothing is decompressed, decrypted or executed. Data outside the file, overlapping or duplicate image data, a missing or repeated data source and hash mismatches fail closed. The devicetree is bounded by the fixed 16 MiB allowance; external image data is streamed from disk. Refs #7129 * fix(artifacts): bound FIT configuration references and suggest analysis only for plain images * fix(artifacts): retain buffered FIT stream cancellation * test(artifacts): gate FIT faults on the observed read phase * fix(artifacts): verify FIT links and summary identities * fix(artifacts): bound FIT diagnostics and retain unknown signatures * fix(artifacts): compare FIT declarations and resolved data links * fix(artifacts): admit FIT raw probes through the shared loader contract * fix(artifacts): preserve FIT field availability independently * fix(artifacts): isolate nested entry metadata from reader facts --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> Co-authored-by: gensokyo-dev <342580529+users.noreply.github.com> |
||
|
|
64196b08ca |
feat(artifacts): inventory and extract ESP32 firmware images (#7498)
* feat(artifacts): inventory and extract ESP32 firmware images ESP32-family app and bootloader images (magic 0xE9) had no reader, so open_binary refused OTA downloads, app partitions and bootloaders. Add the esp-image container format behind inspect_artifact and extract_artifact. A pure decoder reads each byte once and keeps only fixed-size fields. Derived facts cover the chip, from a table cited to ESP-IDF v6.1; segment classification as ESP-IDF's should_map and should_load; checksum and appended SHA-256 results; app and bootloader descriptors; Secure Boot v2 signature blocks, observed and unverified; and undescribed trailing byte ranges. Truncation and undescribed bytes make coverage unknown. ESP8266 images are refused with a specific reason, and ciphertext stays unrecognized. Add the format to every target, Evidence, snapshot, live-summary and artifact vocabulary, document it, and add an optional verify:esp-images lane that compares esptool-built images with esptool image-info and espsecure signature-info-v2. Refs #3615 * test(artifacts): run the ESP image lane on esptool v5.6.0 The lane compared descriptor fields only when esptool image-info printed one, so a descriptor that REA reports and esptool does not print passed without comparison. Compare the descriptor kind in both directions. Record that the lane passed for all 13 images with esptool and espsecure v5.6.0, the version the layout facts cite, as well as with 4.12.0. * refactor(artifacts): define ESP image layout sizes once The decoder and the derived facts each defined the segment-header, appended-digest and flash-sector sizes, the erased-byte scan and the offset formatter. Define them once with the other fixed-layout structures and import them in both places. The signature slot count is the one constant that drives the slot scan. Correct the observedEnd comment: it is the end of the last chunk read. * fix(artifacts): report ESP-IDF's segment length limit by chip ESP-IDF's verify_segment_header rejects a segment of 16 MiB or more unless the chip maps flash through 32-bit cache addresses (SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP: ESP32-S3, P4, C5, C61, H4 and S31 in v6.1). Record that capability in the chip table and add a limitation for such segments; unknown chips get none. `loaded` repeats should_load. It does not mean the bootloader accepts the segment: verify_load_addresses still rejects one outside the chip's RAM, which REA does not model. Say so in the docs, the skill reference and the inventory limitation. * test(artifacts): check ESP lane tools first and verify extraction The lane started work before checking its tools, so a missing RISC-V target, ld.lld, esptool or espsecure surfaced as a raw spawn or command error. Check each one before building and name the variable to set. Warn when esptool is not v5.6.0, the release the layout facts cite. Assert each segment's class for the ESP32-C3 app, its variants and the bootloader, as the Xtensa image already did. Extract the app and the signed image through the CLI and compare every file with the bytes at esptool's segment offsets or in the appended signature sector; the source's SHA-256 must be unchanged and equal the reported root_sha256. * docs(artifacts): state what the ESP image lane does not establish The Verification section listed the lane's checks but not its gaps: only ESP32-C3 and ESP32 images come from a real producer, no real project build, OTA download or flash dump is inspected, no signature is verified, and the lane does not run in CI. Record the timing of the final lane run on esptool v5.6.0. * fix(artifacts): compare ESP segment declarations Segment entries hash only their data, so compare_artifacts reported a segment that moved to another load address with the same bytes as unchanged; only the image itself changed. Compare each segment's load_addr and data_len as its declaration, as Node SEA and PyInstaller members are compared, and count a changed declaration as a metadata change, also when content is unavailable. Header offsets are layout and the classification is derived, so neither is compared. * test(artifacts): run ESP lane commands as owned process trees The lane ran its tools through execFile. A timeout killed only the direct child, so a linker or assembler that Clang or GCC had started could keep running while the lane removed its workspace. Run every command through createVerifierCommands, check the tools inside withVerifierCleanup, and remove the workspace only after commands.close() has stopped every tree; a failed close keeps the workspace. Only a nonzero exit now counts as a refusal or an expected esptool failure; timeouts and spawn failures propagate. Supervising each command roughly doubles the lane's run time. * test(artifacts): cancel ESP decoding after its first decoded chunk The cancellation test requested cancel or close on setImmediate, which can land while the file is still being opened and checked, so it never showed that decoding had started. It also passed against a reader that ignored both requests while decoding. Acknowledge the decoder's first chunk, then cancel or close, join the operation, and assert that no later chunk reaches the decoder and that the reader ends closed. * docs(artifacts): record which ESP metadata comparison ignores Segments are compared by their declaration. The image's and the signature blocks' format_metadata are not: every field comes from their own bytes, which content comparison already covers, and a block's image_digest_matches follows the image's content. * docs(artifacts): state that ESP mmu_page_size is a base-2 logarithm The app descriptor's mmu_page_size keeps ESP-IDF's name and value, the MMU page size in log base 2 as esp_app_desc_t declares it, so 16 means 64 KiB. Say so in docs/esp-image.md and the schema comment; a reader could otherwise take 16 as 16 KiB. * fix(esp-image): retain member consumption and share lifecycle regressions * test(artifacts): scope MCP catalogs and budget full-schema validation * test(artifacts): verify compact output profiles and document bounded catalogs * test(artifacts): close readers when cleanup-test admission fails * test(artifacts): compare ESP image limitations with their owners The decoder and reader tests froze complete limitation sentences, so a harmless rewording failed them. The wording now has two owners: ESP_IMAGE_LIMITATIONS in espImageFacts.ts, which the decoder, the inventory and the reader use, and ESP_DESCRIPTOR_LIMITATIONS beside the descriptor decoder. Tests compare delivered limitations with the owner, called with the facts each case establishes (segment index, declared and available bytes, offsets, chip, page range), next to the structured assertions they already make. Delivered text is unchanged. * test(esp-image): assert structured facts and owned guidance * fix(esp-image): keep spi_flash_mode and descriptor fields before a truncated tail ESP-IDF v6.1's esp_app_desc_t declares spi_flash_mode at byte 181, after mmu_page_size, as the committed reference layout shows; the descriptor now keeps it as stored. The decoder also required all 256 descriptor bytes, though it reads none past byte 181, so a file ending in the reserved tail lost the version, project, digest and revision facts it does hold. The app descriptor now needs only its fields; the segment's truncation is reported as before. * test(esp-image): pin the P-192 public key digest to espsecure's layout espsecure packs ECDSA signature blocks as "<BBBx32sB64s64s1031x" and zero-pads a 48-byte P-192 point to 64 bytes, so the signature starts at byte 101 for every SHA-256 curve. signature_info_v2 hashes sig_block[36:101] and _digest_sbv2_public_key the curve ID with the padded point. No test built a P-192 block; this one checks public_key_sha256 against that definition. * fix(esp-image): keep each app descriptor field the file holds in full A file can end anywhere inside the 256-byte esp_app_desc_t. The decoder needed every field byte, so a cut at byte 176 dropped the version, project and app_elf_sha256 it does hold. Once the 4-byte magic identifies an app descriptor, each field is now kept when the file holds all of its bytes and is null otherwise; observed_length records where the descriptor ends, so a cut field is told apart from text that is not UTF-8. The fields after the magic become nullable in the metadata schema. * fix(esp-image): report a signature block whose image digest does not match A CRC-valid Secure Boot v2 block can carry another image's digest. The block recorded image_digest_matches false, but no limitation said so, unlike a checksum or appended-SHA mismatch, so CLI and MCP summaries showed only the generic unverified note. The mismatch is now a limitation; coverage stays complete and signature_status stays unverified. The three other signature-sector limitations move into ESP_IMAGE_LIMITATIONS with their text unchanged, so all ESP image wording has one owner. * refactor(esp-image): remove redundant descriptor byte guards --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
18a8e71c9f |
feat(artifacts): add U-Boot legacy uImage reader (part of #7129) (#7234)
* feat(artifacts): add U-Boot legacy uImage reader (part of #7129) Recognize legacy uImages by their 0x27051956 magic and inventory them as containers: 64-byte header facts (arch/os/type/compression raw and named, load/entry addresses, name, timestamp) with header and data CRC32 verified, stored payload extractable as payload.bin, and multi-file images split from the stored size table into image-<n>.bin. Compressed payloads stay as stored; nothing is executed or decompressed. Wires the format through classification, the artifact reader dispatch, extraction, and the evidence/snapshot format vocabularies. Related to #7129 (uImage part only); HEX/SREC and FIT are out of scope. * fix(uimage): preserve aligned component ranges and exact header facts * fix(uimage): retain buffered members through consumption and cancellation * fix(uimage): preserve active read and validation failure precedence --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
e78ac1a55b |
feat(artifacts): read UnityFS AssetBundle containers (#7699)
* feat(artifacts): read UnityFS AssetBundle containers inspect-artifact and extract-artifact now recognize the UnityFS signature and treat format versions 6 through 9 as containers. Header facts (format version, player/engine strings, declared size, dataflags, blocks-info bounds and the declared 16-byte data hash) are retained alongside a directory of CAB-* and .resS members. Member bytes stream on demand: only the blocks covering the requested member are read and decompressed with bounded expansion and cancellation. Bundles declaring asset-bundle encryption keep header facts and report unknown directory coverage. LZMA blocks-info reports unknown coverage; LZMA member reads fail as unavailable while the directory stays readable. Malformed counts, out-of-stream members and declared sizes beyond the file fail as format errors. UnityFS classifies by bytes in root detection, inventory graph construction and desktop inspection, which emits a unityfs-header fact. Validation: tsc --noEmit, oxlint (no new findings on touched files), 17 reader tests covering LZ4HC/uncompressed tables, blocks-info at end, format 6 without padding alignment, multi-block members, malformed input, unsupported compression, cancellation and abandoned streams; full artifacts/domain/conformance suites pass. Verified against one real YooAsset bundle (Unity 2021.3.32f1, format 8, LZ4HC): the streamed SerializedFile contained its managed assembly byte-identical to a UnityPy extraction. Other producer variants unverified. * fix(unityfs): own bounded member reads and preserve partial evidence * refactor(unityfs): clarify producer revision flag decisions * fix(artifacts): preserve coverage authority and bound UnityFS block work --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
c36971953c |
feat(artifacts): inventory and extract Intel HEX and Motorola S-record regions (#7136)
* feat(artifacts): inventory and extract Intel HEX and Motorola S-record regions open_binary refused Intel HEX and S-record programming files as an unsupported format, so inspect_artifact and extract_artifact could not answer which bytes load at which addresses. Recognize both encodings by a fully valid first record and decode them statically into address-contiguous regions, each an inventory entry named 0x<start>-0x<end>.bin and extractable as raw bytes. Root format_metadata records the encoding and variant, record counts, unique and duplicate bytes, address bounds, termination, declared start address, S0 header and validated S5/S6 count. Gaps are never filled; start addresses are declared facts, not proven entry points. Checksum, record-type, byte-count, line-length, overlap-conflict, address wrap and post-termination errors fail closed with the line number; a missing termination record leaves coverage unknown. Decoding is bounded by a 128 MiB file ceiling (decoded bytes are at most half the file and are reserved after the size check) and 65,536 address-discontiguous runs. Refs #7129 * fix(artifacts): refuse Intel HEX extended address records with a non-zero address * fix(artifacts): bound HEX region copies and retain stream cancellation --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
c27560e434 | fix(artifacts): classify selected package names | ||
|
|
779d548c4e | fix(artifacts): preserve selected ASAR companion paths | ||
|
|
a7004c7df1 |
fix(filesystem): finish executable and project span reads
Reuse the positional range owner for target metadata, Hopper Mach-O selection and Kuna spans. Preserve physical failures, completed span evidence and cleanup ownership across cancellation and short reads. Validated 147 focused file and lifecycle tests; ten new cases reproduced failures against the prior implementation. |
||
|
|
a30ffd27a6 | refactor(dos): centralize MZ admission and load-image evidence | ||
|
|
92bdb4443f | refactor(pe): share CodeView range interpretation | ||
|
|
deed39f7c4 | refactor(pe): share optional-header facts across readers | ||
|
|
b9ee8fe057 | refactor(pe): centralize fixed COFF header decoding | ||
|
|
0eb3919d69 |
fix(artifacts): admit raw UDRW disk images (#7106)
* fix(artifacts): admit raw UDRW disk images Raw (UDRW, UDTO) disk images have no UDIF koly trailer, so target admission and root inventory both refused them as unsupported binaries. Recognize disk images in one domain owner (koly trailer, GPT, Apple partition map, MBR, or an unpartitioned HFS+/HFSX volume header) that both boundaries consume. hdiutil reports "has no checksum" for these images; the native reader now treats that status line as an explicit absent checksum, records the nonzero verify command, attaches read-only, and reports that integrity was not verified. Checksum mismatches and unrecognized images are still refused. Positional range reads used by these probes now fill until end of file so short host reads cannot hide a signature. Fixes #5687 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(artifacts): read disk image signature windows at the recognizer Target admission passed its first unfilled 4 KiB read to the raw-image checks, so a short host read could hide a GPT, APM, MBR or HFS+ signature that inventory (which fills its prefix) still observed. The recognizer now reads its own leading window through the caller's filling positional read, and target admission fills its format-probe prefix as well. The controlled short-read regression now covers target admission alongside inventory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
69a2faa120 |
feat: add FreeBuff agent support for REA setup (#2736)
* feat: add FreeBuff agent support for REA setup Register FreeBuff as a supported setup client using the shared user agents directory (~/.agents/mcp.json with mcpServers, skills in ~/.agents/skills), which matches what FreeBuff Desktop loads. Adds the client definition, boundary tests, supported-agent docs, and the skill reference client list. * fix(freebuff): detect FreeBuff from its profile directory, not shared .agents The ~/.agents marker made FreeBuff appear installed for any home where REA had installed shared skills (the default skill destination, also Gemini CLI's), producing false doctor failures. Detect FreeBuff from its own fixed profile directory ~/.config/freebuff-desktop instead, and add a regression test covering a home with only the shared agents skill directory. * fix(setup): require product evidence for FreeBuff discovery Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request. * fix(uninstall): retain unverified shared client configuration * fix(clients): preserve scoped removal evidence * fix(doctor): omit undefined selectedClientIds under exactOptionalPropertyTypes Passing selectedClientIds explicitly as undefined fails typecheck on this branch (TS2379), which blocks the focused test workflow before any test can run. Spread the option only when defined. * fix(update): separate ownership evidence from product applicability rea update's maintenance scope inspected only product applicability evidence, so when a FreeBuff profile was absent but REA already owned a version-pinned row in the shared ~/.agents/mcp.json, the plan omitted freebuff and left the integration stale. FreeBuff now declares its registration storage as shared, which proves ownership of an owned row but never product applicability, and maintenance requests ownership evidence through that declaration instead of reinterpreting the shared paths. Doctor and setup keep readiness evidence, foreign rows stay out of maintenance, and the Doctor exactOptionalPropertyTypes fix makes the focused test workflow runnable. * test(dotnet): split oversized operand extent diagnostics describe The describe callback reached 162 lines (max 150), failing max-lines-per-function and blocking the pre-push check for this branch. Move the single-case extent scenarios into their own describe; no test content or order changes. * fix(update): preserve ZCode's disabled shared registration during maintenance The shared user agents file doubles as ZCode's fallback, where `enable: false` disables the registration. Ownership-based maintenance read that row as a FreeBuff registration, whose format does not recognize the flag, so the row was selected and the emitted setup command rewrote it, dropping the flag and silently re-enabling a registration the user had disabled. registrationActivation now honors `enable: false` for any client whose registration storage is shared, because the activation fact binds every reader of that storage. Maintenance leaves such rows out; doctor reports them as stale, matching ZCode's own treatment. * fix(doctor): let explicit client selection authorize the config read When an ACL or an inaccessible shared parent made every access probe fail, a client selected by name was omitted before the configuration read could return its unreadable-config detail, so doctor reported it as not detected with installation remediation: an unresolved selected path collapsed to absence. An explicit selection now authorizes the read outright and the probes serve automatic discovery only. A selected client with an unreadable config reports invalid with the read failure; one with no config reports missing; automatic discovery still probes before inspecting. * fix(uninstall): share shared-storage checks between ZCode and FreeBuff clients() queued ~/.agents/mcp.json twice: once as zcode_fallback and once as freebuff. ZCode has no discoveryPaths, so its strict read still blocked uninstall on malformed shared text, despite FreeBuff's new retain-and-continue behavior. For a valid owned entry, ZCode removed it first, so FreeBuff reported skipped rather than removed. Make the shared file's checks and removal one shared decision: - Add zcodeDiscoveryPaths to ZCode so it has its own applicability evidence. - Gate zcode_fallback push on applicable, not just zcodeFallbackPath presence. - Report shared storage ownership as one decision for both clients: FreeBuff and ZCode now use clientOwnershipEvidencePaths together, so a recognizable REA-owned row proves ownership once for the shared storage, and both clients report the same result consistently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(uninstall): merge duplicated host and prove shared ownership from owned rows Uninstall.ts declared systemUninstallHost twice, preventing module load, with the exported copy returning only clients and the second copy missing clientWriteBlocker. Merge into one exported host carrying both blockers. hasOwnershipEvidence used access() existence, so an unrelated malformed ~/.agents/mcp.json established ownership and blocked every removal. Ownership now requires a readable, recognizable REA-owned row via the injected filesystem, so unrelated shared data stays retained. Also cover ZCode discoveryPaths in its path test. * fix(uninstall): keep denied product-local configurations fail-closed Unproven product applicability marked every configuration path of that client unverified, so a denied ZCode profile turned an unreadable product-local config into a retained item: uninstall continued and could report complete with REA still registered. The retain-and-continue exception now applies only to storage REA does not own, classified once by clientSharedRegistrationPaths (shared configuration plus another product's same-scope fallback). Covers the Greptile P1 on Uninstall.ts. Validation: the new test fails on the pre-fix Uninstall and passes after it; freebuff/zcode/updateMaintenance/bom/dsh suites green; clientLifecycle, clientRegistrationStatus and claudeDesktop keep the same 8 host failures as the pre-merge baseline (symlink EPERM, stale-vs-aligned on Windows). * fix(update): retain FreeBuff when ZCode reads the shared fallback Maintenance deduplicated clients on the path each inspection read, so ZCode's fallback view of ~/.agents/mcp.json marked that file "covered" and dropped FreeBuff from the scope. ZCode setup writes ~/.zcode/cli/config.json and deliberately leaves the fallback untouched (docs/client-configuration.md), so the emitted command refreshed only ZCode while the shared row both products load stayed pinned to the old package version. Each setup action rewrites only its own configuration path and no other action rewrites the shared row, so every selected client keeps its own maintenance action; the read-path covered/deduped filter is removed. Covers the Codex P2 on UpdateMaintenance.ts:104. Validation: the new regression fails on |
||
|
|
a891bb80ae |
refactor(filesystem): preserve admitted file facts
Return the validated descriptor and its original metadata from regular-file admission. Propagate that contract through owned reads, hashes, snapshots, artifact inventory and provider file workflows instead of replacing initial facts with another stat. Keep arbitrary output-handle operations separate. Preserve final descriptor/path identity proofs, borrowed-source verification, BigInt precision, cancellation provenance and failed-close ownership. Remove the obsolete source and owned-ZIP baseline stages and update their consumers and regressions. Tie read completion faults to actual reads instead of the retired duplicate stat; instrument real handles without fake handle wrappers. Validation: fresh runtime/catalog build; focused source, lifecycle, filesystem, CLI/MCP and authored provider-fixture tests; full static checks; docs checks; test discovery; duplication check. Platform-specific cases remain skipped on macOS. No installed provider or device behavior was verified. |
||
|
|
cab78de506 |
feat(ghidra): analyze GameCube/Wii DOL executables through Ghidra (#6240)
* feat(domain): parse and validate GameCube/Wii DOL headers Add a pure parser for the 0x100-byte DOL header (7 text and 11 data slots, BSS, entry point). Used slots must lie after the header and inside the file and the 0x80000000..0x81800000 load window; text slots are 4-byte aligned; sections may not overlap in memory or in the file; the entry point must be inside a text section. BSS may overlap data sections, as .sdata/.sdata2 do in shipped DOLs. Refs #1741 * feat(binary): admit caller-selected GameCube/Wii DOL targets * feat(ghidra): import GameCube/Wii DOL targets through a section-map pre-script * test(ghidra): cover DOL launcher arguments, attestation and raw profile digests * test(ghidra): add the real verify:ghidra:dol lane and DOL docs * fix(ghidra): read only the DOL header and section ranges instead of the whole file * test(ghidra): derive DOL lane addresses from readelf and admit Gekko from the install catalog * fix(ghidra): attest DOL block permissions, space, overlay and load state * fix(ghidra): keep load-image permissions optional for older inspections * fix(contracts): accept DOL targets in binary_session output * fix(ghidra): adapt the DOL lane to the current upstream address schema Validate DOL load-image coordinates with the upstream observed-address schema, drop a duplicate import left by the rebase, and re-pin the raw profile digests to the unmodified upstream resolver. * fix(ghidra): preserve bridge inventory symbol provenance * fix(ghidra): align DOL verification with shared workflow contracts * feat(domain): parse and validate GameCube/Wii DOL headers Add a pure parser for the 0x100-byte DOL header (7 text and 11 data slots, BSS, entry point). Used slots must lie after the header and inside the file and the 0x80000000..0x81800000 load window; text slots are 4-byte aligned; sections may not overlap in memory or in the file; the entry point must be inside a text section. BSS may overlap data sections, as .sdata/.sdata2 do in shipped DOLs. Refs #1741 * feat(binary): admit caller-selected GameCube/Wii DOL targets * feat(ghidra): import GameCube/Wii DOL targets through a section-map pre-script * test(ghidra): cover DOL launcher arguments, attestation and raw profile digests * test(ghidra): add the real verify:ghidra:dol lane and DOL docs * fix(ghidra): read only the DOL header and section ranges instead of the whole file * test(ghidra): derive DOL lane addresses from readelf and admit Gekko from the install catalog * fix(ghidra): attest DOL block permissions, space, overlay and load state * fix(ghidra): keep load-image permissions optional for older inspections * fix(contracts): accept DOL targets in binary_session output * fix(ghidra): adapt the DOL lane to the current upstream address schema Validate DOL load-image coordinates with the upstream observed-address schema, drop a duplicate import left by the rebase, and re-pin the raw profile digests to the unmodified upstream resolver. * docs(ghidra): qualify the DOL memory window * refactor(ghidra): own DOL BSS ranges in the parsed header * docs(ghidra): record real DOL workflows and task costs * docs(ghidra): record final DOL integration verification * fix(mcp): share the native procedure search row contract * docs(ghidra): record public procedure search verification --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
6843dbea9b | fix(native): preserve bounded JVM identity before FAT admission | ||
|
|
651afa4455 | fix(elf): validate declared file extents before provider admission | ||
|
|
5796220f23 | fix(native): validate Mach-O command framing before admission | ||
|
|
d9d77726ff | fix(pe): distinguish unsupported overlapping header layouts | ||
|
|
2732d538e8 | fix(session): own target admission descriptors through finalization | ||
|
|
bd4f5e9c19 |
fix(parsers): preserve format evidence and caller input identity
Retain bounded FAT and offset-tagged PE observations through archive hashing, classification, and content nodes. Preserve PyInstaller member paths according to the observed carrier dialect and share APK v1 signing-name semantics. Read SQLite's implicit sqlite_schema table without inventing a stored schema declaration. Distinguish unsupported ELF numbering and decoded-name admission from malformed data and fixed scan allowances. Preserve Sigrok basenames and classify matching explicit input-format refusals at their owning boundary. Validation: 554 distinct tests passed, 3 skipped across serial focused runs; build, typecheck/lint, docs, formatting, and discovery (2141 files) passed. Sigrok command-boundary simulators do not establish real-tool decoding. Small repeated public PyInstaller CLI runs had equivalent inventory facts; warm median elapsed 0.5431s before / 0.5426s after, with no speed claim. Fixes #6733 Fixes #6741 Fixes #6722 Fixes #6732 Fixes #6736 Fixes #6734 Fixes #6764 Fixes #6766 Refs #6739 |
||
|
|
39d1b2d395 | refactor(targets): preserve ambiguous MZ header evidence | ||
|
|
6b8f4f7528 |
fix(native): admit universal Mach-O files without a host slice (#5501)
* fix(native): admit universal Mach-O files without a host slice FAT Mach-O admission selected only the host's slice and rejected a valid container whose slices are all foreign, so list-architectures returned target_unavailable instead of the container's inventory. A thin foreign image was already admitted. Prefer the host's slice and otherwise select the first declared supported slice. Remove the Ghidra installation probe's re-parse under other host architectures, which existed only to work around the rejection. Fixes #5404 * fix(native): select the first valid foreign FAT slice Without a host slice, FAT selection took the first declared slice even when it was too short for its Mach-O header, rejecting a container whose later foreign slice is valid. The Ghidra decompiler probe then reported such a foreign-only decompiler as unknown rather than incompatible. Select the first foreign slice that can hold its header; a malformed host slice still fails. * fix(native): select foreign FAT slices from every declaration Foreign-slice fallback chose among architecture families after keeping only each family's first declaration, so an undersized first arm64 subtype hid a valid later arm64 subtype. Select from all declarations, and report the deduplicated families separately. The host-slice rule is unchanged. Move the FAT selection tests into their own block. * fix(native): admit only unambiguous foreign FAT families With no host slice, a family declared more than once, such as arm64 and arm64e, has no provider-neutral choice: IDA analyzes the recorded slice while Hopper prefers its own subtype. Select only families declared exactly once and keep ambiguous foreign-only containers rejected, as on main. * fix(ghidra): decide FAT decompiler compatibility from validated families Slice selection now refuses a foreign-only FAT table that declares one family more than once, such as arm64 and arm64e, and the decompiler probe reported that refusal as unknown, so an x64 host accepted an arm64-only decompiler. When selection fails, read the table's validated CPU families and report the decompiler incompatible when they exclude the host. Selection and host exclusion now have separate owners in binaryTarget.ts. |
||
|
|
35d6d5bb0a |
fix(artifacts): admit ZIP archives after unclaimed leading bytes (#5803)
* fix(artifacts): admit ZIP archives after unclaimed leading bytes ZIP recognition required the archive at byte 0, so a ZIP behind a script or self-extractor stub was refused as an unsupported binary format although standard readers accept it. Target resolution and root inventory now locate a trailing single-disk ZIP from its end record, central directory and first local header, whether member offsets include the leading bytes or not. Leading bytes any executable header family claims keep their executable route. Fixes #5732 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(artifacts): share the root ZIP family across recognition paths The trailing-ZIP fallback named a stub-prefixed root `.app` archive `zip`, while root inventory and the leading-signature route name it `app-pack`. The root mapping now lives once in `zipRootPackageFormat` and both target resolution routes and root inventory use it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b81431d7ff |
fix(artifacts): report a stable symlink loop as a path resolution failure (#5571)
ELOOP raised while resolving the caller-selected path (access/realpath) is a symbolic link loop or over-deep chain in that path, not evidence of a change. Classify filesystem failures by resolution stage so only ELOOP from opening the canonical path with symbolic links rejected keeps the "target changed while being opened" reason. The structured code, category and retryability are unchanged. Fixes #5521 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
7c6c25dda7 |
fix(artifacts): report target applicability in session discovery (#5763)
* fix(artifacts): report target applicability in session discovery * fix(artifacts): preserve resolved target applicability facts * fix(target): retain bundle metadata for explicit formats |
||
|
|
44521d3d75 |
refactor(macho): share thin header CPU interpretation
Give partial thin-header facts one domain owner and reuse them for standalone target admission and Mach-O load-command inspection. Preserve each consumer endianness policy and header/command checks; remove the FAT-only parser names. Refs #5542. All 246 focused checks and six public CLI archive/image controls passed; typecheck and lint passed. |
||
|
|
497037e6e3 |
fix(macho): validate FAT slice format and CPU identity
Use observed thin-header facts before target architecture admission, reject archive payloads, and retain far-offset root inventory through bounded reads. Retry complete bounded FAT table reads. Refs #5462, #5542. Focused native/filesystem checks passed (245 plus 70 after the table retry). Public MCP inventory parity and unchanged token estimates verified; no external analysis engine execution claimed. |
||
|
|
5fa4defcbc |
feat(artifacts): inspect and extract Godot PCK with retained facts (#3634)
* feat(artifacts): read Godot PCK packs Add a Godot Engine PCK artifact reader for standalone packs and packs embedded behind an executable trailer (formats 2 and 3). Members are uncompressed byte ranges verified against their declared MD5 on read. Encrypted directories, sparse bundles, patch removal entries, unknown flags and format 1 fail closed as unavailable; encrypted members are reported without being read. inspect-artifact and extract-artifact recognize standalone packs by their GDPC magic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(artifacts): bound Godot PCK metadata and own member streams Cap member paths at 4096 bytes and the retained directory at 64 MiB before allocation. Read members with positional chunk reads through pipeline so cancellation is typed, abandoned consumers release their source, and the shared descriptor stays reader-owned. Retain the root descriptor for godot-pck inventory, as for ZIP and universal Mach-O. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(artifacts): complete Godot PCK facts, integrity and selected views * fix(artifacts): preserve atomic-root inventory Evidence * fix(artifacts): bound aggregate PCK member expansion --------- Co-authored-by: Samucahub <151155051+Samucahub@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com> |
||
|
|
e65c3955f9 |
fix(filesystem): preserve digest failures through cleanup cancellation
Record cancellation at file checkpoints and before owner handoff. Keep physical hash failures, exact reasons, completed facts and failed-close owners distinct through artifact and provider projections and cleanup retries. Refs #4598. Validated with 566 passing affected tests and 22 platform skips; final Kuna cleanup reason rerun passed 43 tests. No Android device or real JADX/Kuna execution claimed. |
||
|
|
fc791bb606 |
fix(paths): select caller paths through symlinks and .. as the filesystem does (#4067)
* fix: select caller paths through symlinks and .. as the filesystem does CLI adapters, binary target resolution, the reverse-engineering service and the objdump and Rizin command builders made caller-selected paths absolute with path.resolve, which collapses `link/..` lexically. On POSIX the filesystem follows `link` first, so these commands inspected, hashed or launched a different file and returned internally consistent Evidence for it. absoluteCallerPath now owns that step: on POSIX it prefixes a relative path with the working directory and keeps an absolute path as spelled; on Windows, where `..` resolves lexically, it keeps win32.resolve. Fixes #3864 Fixes #3911 Fixes #3912 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep firmware, WASM list and output-root paths on the selected file Review follow-up. The CLI already passed firmware and WASM paths through absoluteCallerPath, but snapshotFirmware and SafeOutputTree.create re-resolved them lexically, and the WASM glue and candidate lists still used resolve, so those inputs could still select a sibling file or create output beside the intended directory. absoluteCallerPath now also drops `.` segments and repeated or trailing separators on POSIX, which never change the named file, so selected paths such as `./module.wasm` keep matching their glue references exactly. Every `..` is still left for the filesystem. SafeOutputTree keeps host path syntax; its platform argument selects only the Windows name policy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep directory requirements and relative cwd in caller paths Review follow-up. absoluteCallerPath stripped a trailing `/` or `/.`, so `file/` selected the regular file instead of failing with ENOTDIR; it now keeps one trailing separator. A relative cwd option was appended to the root; it is now made absolute without collapsing `..`. WASM glue matching resolved local literals lexically, so a module selected through `link/..` matched only by basename; the adapter now compares both sides through absoluteCallerPath and still reports each candidate as given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
2daeff4b24 |
fix(application): normalize owned target admission cancellation
Normalize only the exact aborted signal reason, retaining unrelated failures and descriptor ownership after cleanup failures. Refs: #3197, #3265 Co-authored-by: SII-YDD <38822679+SII-YDD@users.noreply.github.com> |
||
|
|
9387282274 |
fix(ghidra): reconcile GNU MIPS ABI declarations
Parse bounded GNU file-scope FP/MSA attributes once, retain absent versus uninspected declarations, reject conflicts and unsupported argument ABIs, and include observed facts in profile identity. LE/BE filesystem and profile regressions pass; real Ghidra/MIPS behavior remains unverified. Fixes #3096 Co-authored-by: Aurelio Bernal <aurelio@bernalr.com> |
||
|
|
ec271121e4 |
fix(artifacts): preserve path identity and exclusion applicability
Normalize path facts once at the owning filesystem boundary, preserve caller spelling and unavailable inventory members, and retain typed read failures. Record exclusion entry kinds so only proven directories can establish descendant symlink targets; omitted legacy kinds stay unknown. Reviewed fixes include #1969, #2642, #2759, and #2994. Validation: 26 reference graph source tests passed; prior artifact checks passed 275 tests with one Windows-only skip. Updated compiled import workflows are included in final validation after regeneration. |
||
|
|
729ca2ab6a |
fix(ghidra): report unapplied PE CodeView PDB limitation (#2283)
* fix(ghidra): report unapplied PE CodeView PDB limitation (#2259) When Ghidra analyzes a PE target that references companion debug symbols in its CodeView (IMAGE_DEBUG_TYPE_CODEVIEW / RSDS or NB10) debug directory, Ghidra's headless analyzer cannot automatically locate or apply the companion PDB from isolated runtime directories without companion admission. Procedure names remain analysis-generated (FUN_<address>). Parse CodeView debug metadata (RSDS GUID/age and NB10 age) during PE target resolution, and report an Evidence limitation informing callers and agents that referenced debug symbols were not applied and procedure names are analysis-generated. Fixes #2259 * test(pe): group CodeView header coverage separately * fix(ghidra): avoid contradictory PDB limitations * fix(android): make DEX descriptor pattern portable * fix(ci): isolate Linux Hopper process fixture inventory * fix(comparison): recheck historical calls-only changes (#2223) * fix(comparison): preserve incomplete function call evidence Keep missing, unknown, partial and unresolved call relationships unknown in function comparisons and reconstruction claims. Aggregate IDA caller and callee coverage without overwriting uncertainty. Validate with 144 focused tests, typecheck/lint, docs checks and test discovery. Real providers were not verified; the full headless IDA session suite requires unavailable Windows native controls. * fix(comparison): recheck historical calls-only changes --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> * style: format identity comparison and IDA runner --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Lucien <164857476+dakjdakd@users.noreply.github.com> |
||
|
|
168bfe5060 |
fix(target): probe WASM before inferred database routing (#2007)
* fix(target): probe WASM before inferred database routing * test(wasm): execute recovery arguments from native refusal * test(ci): repair fixture alignment and share MCP assertions --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|
|
9c14999efd |
feat(ghidra): support raw NMOS 6502 analysis (#2079)
* feat(ghidra): admit raw NMOS 6502 analysis * test(ghidra): require verified POSIX verifier cleanup * test(ghidra): verify 6502 low-memory raw imports * docs(skill): document raw NMOS 6502 support * fix(ghidra): preserve requested Windows raw source paths * docs(ghidra): include raw 6502 in Windows installation scope * test(ghidra): verify Windows raw junction rejection through CLI and MCP * fix(validation): make fixtures portable and preserve explicit Codex home * fix(ghidra): attest raw mapping state and address space * fix(ghidra): align diagnostics and regression groups * fix(ghidra): bind raw attestation to language address space * chore(ghidra): avoid verifier insertion conflict * docs(ghidra): align linked raw admission guides * fix(ghidra): retain 6502 verifier workspace on failure * test(ghidra): isolate Windows authority doctor fixture * fix(binary): re-admit Windows raw paths on session reopen * test(binary): require fresh provider execution after path change * Constrain 6502 to raw lifecycle and snapshot targets * Bypass saved reads for unadmitted Windows paths * Guard direct CLI snapshot replay on Windows paths * fix(snapshot): gate Windows Ghidra replay on native admission * fix(snapshot): constrain nested 6502 subjects to raw images * test: make dyld slice fixtures portable |
||
|
|
dc038d16bb | fix(apple): preserve archive signatures and metadata byte identity | ||
|
|
c9fed50691 |
fix(targets): recognize Windows headers after short DOS stubs
Observe MZ header declarations and signature uncertainty at the domain boundary, then reuse those facts in bounded target resolution, inventory, and Go PE parsing. Preserve DOS relocation ownership and fail closed when the relevant bytes remain unexamined. Validation: 59 domain tests, 130 target/Go boundary tests, and public CLI inspection of a clang/lld-link PE DLL with a short DOS header. Fixes #2172. |
||
|
|
672bdea21f |
fix(target): recognize binary plists by magic under any extension (#2133)
Target resolution admitted a property list only when its name ended in .plist, so keyed archives with other extensions (for example .archive) were rejected as an unsupported binary format before any plist tool ran. Classify bplist00 bytes as a plist, as the artifact inventory already does. Fixes #2129 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
75a4a14fa0 | fix(artifacts): compare package signatures without ASCII folding (#2069) | ||
|
|
98d8470d36 |
fix(io): consolidate managed snapshots and retain cleanup ownership
Reuse managed snapshot admission and hashing in sequential path comparisons, retaining caller paths and completed inspection Evidence on later failure. Preserve exact failed-close owners alongside typed read and cancellation failures, and retry them through caller-owned resource scopes. Require canonical Hopper lease identities, remove signed offset coercion, and repair stale setup cleanup expectations that failed CI. |
||
|
|
edf46248f2 |
fix(targets): project invalid raw-binary loads as caller input (#2004)
* fix(targets): project invalid raw-binary loads as caller input * fix(targets): name real load options and cover DOS COM kind pairing |
||
|
|
b38429cb6a |
fix(native): preserve universal Mach-O container identity
Keep FAT container format distinct from selected slice architecture through target admission, Evidence, snapshots, and CLI/MCP lifecycle results. Preserve native, Hopper, Ghidra, extraction, and dylib routing for the Mach-O family. Reject selected FAT ranges overlapping their table or too short for a Mach-O header. Replace empty-slice fixtures with in-bounds executable headers and cover thin, universal, single-slice, FAT64, and swapped containers. Validation: static and architecture checks, generated docs, targeted producer and public MCP tests. Provider routing uses controlled fixtures; no live Hopper, IDA, JADX, or Ghidra analysis was performed for this change. |
||
|
|
f28f338283 |
fix(targets): remove path advice for format refusals
Readable executable format refusals report their source format reason and an unsupported-target category instead of misleading missing-path advice. Preserve actual path/permission errors, WASM static recovery, and native target source inspection. Verified on Linux x64 through actual CLI/fresh stdio MCP: three NE/LE/LX controls, exact canonical projection parity, unchanged bytes, responsiveness and a missing-path control. 103 focused tests across nine files, full static gate and generated documentation passed. Fixes #1979 Refs #1852 Co-authored-by: Ha1baraA11 <243105435+Ha1baraA11@users.noreply.github.com> Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> |
||
|
|
e9fe6437a7 |
feat(ghidra): admit verified MIPS16 shared ELF images
Admit the verified ELF32 o32 MIPS32r2 MIPS16 shared-image profile after complete source load and relocation inspection. Preserve caller-selected bytes, pin the endian-matched language, and report per-address decoder context. Refuse unverified relocation shapes with explicit reasons. Verified on Linux x64 with Ghidra 12.1.4: eight source-owned public CLI/MCP controls, original-artifact instruction/pseudocode/export replay, snapshot restore and owned cleanup. 152 integrated focused tests, static checks and documentation checks passed. Fixes #1851 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> |
||
|
|
1f17ac8228 |
feat(target): explain static WASM inspection after native rejection
Explain recognized WASM v1 native-admission rejection with an exact call to the existing static inspection tool and its caller-supplied WABT prerequisites. Preserve selected paths, explicit raw-binary choices, typed missing-tool outcomes and connection usability. Refs #1852 Co-authored-by: SII-YDD <38822679+SII-YDD@users.noreply.github.com> Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> |