Fixes#518. With if_tampered=continue, core_archive_extract writes a ZIP member whose CRC does not match (the mismatch stays in contradictions), as its remediation says.
Fixes#519. core_archive_show counts nested archives that a depth or size limit left unopened, reports a nested_not_opened limitation and marks coverage partial.
Fixes#516 and #517. Archive extraction refuses member names with a colon or a trailing dot or space, which Windows would change (merging two members, or hiding bytes in an alternate data stream).
Fixes#510. The built-in engine lists DNS answers like tshark does: each A/AAAA address keyed by the response's first question, so CNAME chains end at the name asked. Both engines report the dns_answer_attribution limitation.
In Deep mode, Ghidra's pseudo-C uses the names set with native_name_set in the function field, the summary and the code (whole identifiers only, never inside comments, literals or fields); names that can't stand in C or would clash are listed in a limitation.
A stand-in backend no longer replays a recorded 304 without its cached body: such samples are kept for diagnosis, skipped in replay, and a request with no usable answer gets cached_body_unavailable. Builds count them.
Fixes#335. Before a tab is clicked, web_page_states_capture marks the tab its list has selected and clicks it again after the picture, so later states and the next capture see the page as it was.
Fixes#469. craft.json records which coding agent saved the session (agent_session_by). A build or a question continues the session only with that agent; after the builder changes, the new one starts from the brief. A follow-up to an agent with no saved session also gets the brief.
settings_set keeps a test session's engines.only_configured across its settings round trip, so a test that changes a setting still doesn't find this computer's engines. New testing::live_session() finds installed engines for the --ignored live tests; the live website tests use it.
Fixes#339. web_page_states_capture drops the data-craft-state marks an earlier call left before marking, so a capture at a second width opens that width's own controls instead of a hidden one from the first width.
Fixes#451, fixes#452, closes#446. Claude Code's result for a --resume session it doesn't have is recognised (StreamParser::session_missing); the build forgets the stale id and starts a new session from the brief, what is in app/ and what the project kept of the old conversation, and questions answer from the project's files. After every builder turn the project keeps a private copy of the session, which is put back under Claude Code's folder on another computer when it isn't there (never over an existing one).
Fixes#336. web_site_capture keeps the first 4 MiB of the page's HTML; when the page has more, the evidence carries an html_cut limitation with both sizes and the README says page.html is the first part, cut at the size limit.
Test sessions set engines.only_configured (never saved), so Settings::ghidra_launcher and engine_path look only where the settings and the managed store say, not on PATH or in the usual install folders. Tests now pass the same on a machine with Ghidra installed. New locate_configured and ghidra::get::headless_configured are the first half of locate and headless, which return the same as before.
native_function_find works out the offset as a signed value, so an address in a block below the function's entry gives a negative offset ("-0x70") instead of wrapping to a huge number or panicking with overflow checks.
Merges the whole SQLite stack in one commit (#410, #411 and #412): WITHOUT ROWID tables are read in primary-key order, rows older than ALTER TABLE ADD COLUMN show the added columns, and records over the payload cap say which values were cut.
Fixes#406, fixes#407, fixes#408.
Fixes#294. walk_dir returns an error when the root folder can't be listed and keeps each unlistable folder below it; core_archive_show and js_app_map mark those folders, add an unlisted_folders limitation and report partial coverage.
core_archive_show records max_entries and max_total_bytes, and a shared recorded_inventory helper checks a folder's freshness at the scope it was recorded with, so core_archives_compare and the Android, Apple and Harmony graph tools no longer refuse unchanged folders as file_changed.
game_unity_bundle_list adds a files_unread limitation when a bundle has more serialized files than it reads (16) and says "at least N object(s)" in its summary.
In summary mode formats_ai_weights_show saves every tensor in its evidence record with complete coverage, so core_evidence_browse can page through all of them instead of stopping after the first page.
Declared source maps on the script's own loopback origin (http://127.0.0.1 or [::1] with a port) are now resolved against the script URL and fetched with the bounded HTTP client, reporting fetched, bytes or the reason. Other hosts, ports, schemes and remote https maps are still never requested.
app_folder_explain counts files it couldn't open to look inside (unopened_files) and reports partial coverage then, and when its walk couldn't read something, instead of a complete 'nothing points to a runtime'. Fixes#292.
Frozen and light pins keep a project's runtime models in assets/obj; only obj folders beside a .NET project file are left out as build output. Fixes#274.
Listing Frida devices with a remote address returns that remote as one device, marked not contacted, instead of running frida-ls-devices with a -H flag it doesn't have.
build_file_read always shows the first line of a page, cut to 256 KiB with a note when it is longer, so a long minified line no longer reads as an empty page that no offset gets past. Fixes#280.
In Deep mode, a position-independent program is decompiled by name: addresses move between our image base and the one Ghidra loaded it at (the bridge now reports it), with engine_entry and an engine_rebased limitation when they differ.
Triage says a file that starts like an ELF, PE or Mach-O but can't be read is damaged, with the parse error, instead of calling it an unknown format. Fixes#319.
Reopening the same raw bytes with another architecture or entry point replaces the open target instead of silently keeping the first settings and caches. Fixes#305.
Triage of a bare .class file says it is a compiled Java class and recommends the java toolset (java_class_show, java_classes_find) instead of calling it an unrecognised format. Fixes#348.
A .text section that runs past the end of the file is decoded as far as the bytes go, with a text_truncated limitation and partial coverage. Fixes#306.
`app_changes_summarize` decided whether each comparison found changes. For records with `counts` it added added + removed + changed, which left out moves. So an archive or folder comparison whose only difference was a moved file (reported `identical: false`, `moved: 1`) counted as unchanged ("0 of 1 comparisons found changes").
A record's own `identical` verdict now decides when it has one, and moves count otherwise. Archive `counts.changed` keeps its meaning (content-edited files).
**Verified:** a new test of the verdict: a move-only comparison is changed (with and without `identical`), and an identical one is not. The engine's compare tests, clippy and fmt pass.
Fixes#286
`runtime_captures_compare` compared the filesystem dimension by the set of changed paths only. A run that deleted a watched file and a run that created the same file both "changed" that path, so they matched, and the comparison said the two runs were the same.
Each path is now compared together with how it changed (created, deleted or modified). Two deletions of the same file still match, and different paths still differ.
**Verified:** a new test of the filesystem comparison covering deleted vs created (changed), deleted vs deleted (unchanged), different paths (changed), and an `unchanged` effect against none (unchanged). The engine's process-tool tests, clippy and fmt pass.
Fixes#300
The builder's approval check refused dev servers before looking at the safe build list. `npx vite build` is on that list, but it also starts with `npx vite` (a dev server), so it was refused as one, whatever the mode or Auto setting.
A listed build is no longer read as a dev server: `npx vite build` and `cd app && npx vite build` are allowed, while `npx vite` and `npx vite --host …` are still refused. A command in watch mode (`--watch`) is now refused with the same hint, since it never exits either. That includes a listed build such as `npx vite build --watch`. The safe-list match moved into one helper used by both checks.
**Verified:** new cases in the approval tests (three spellings of the build allowed; two server forms and a watch build refused). The engine's approval tests, clippy and fmt pass.
Fixes#291
The engine had its own `write_atomic` (used for `craft.json`, the inbox, reports and session files). Its temp file was named by process only, so two threads saving the same file at once wrote into one temp file. One rename then found it gone ("craft.json: No such file or directory"), and the file could end up with two versions mixed ("trailing characters").
The engine now uses the platform crate's `write_atomic`, which already gave each write its own temp file and kept the file's permissions. It also gains the engine's short retry when Windows briefly can't replace a file another program holds open. There is one atomic writer now; docs/pitfalls.md says so.
**Verified:**
- A new engine test: four threads each save one file 50 times and read it back. Every save succeeds, every read is one whole version, and no temp files are left. It fails against the old engine writer (checked) and passes now.
- The existing "file held open for a moment" test still passes.
- `cargo test -p craft-anything-engine` (397), the platform fs tests, clippy on both crates and fmt.
**Not covered:** two saves that overlap can still each start from what was on disk, so the later one wins for fields that aren't the person's (the person's fields are kept, as before). That's separate from the write itself.
Fixes#273