Commit Graph
20 Commits
Author SHA1 Message Date
morluto 3537e58c1a fix(plist)!: preserve unknown XML scalar identities
Interpret complete scalar source at the XML owner instead of accepting numeric prefixes, permissive date strings or nonempty booleans. Retain malformed content as explicit unknown scalars with original literals and reasons, while preserving the surrounding archive and independent numeric facts.

Share the representation across plist, keyed archive, Interface Builder and entitlement projection; remove the superseded numeric fallback and helpers. Parse date fields as UTC, retain real entity/CDATA semantics, and distinguish native integer/real whitespace without ambiguous whitespace backtracking.

Validation: 276 source tests and 60 compiled/public tests passed, with updated scalar regressions rerun; static, architecture and docs checks passed. Native macOS plutil controls and CLI/MCP source-hash/time-zone controls executed. No Linux/Windows or deep-provider qualification. Tiny completed CLI task costs recorded; no performance improvement claimed.

BREAKING CHANGE: Unresolved XML scalar values now use $plist_type unknown wrappers with element, literal and reason. This replaces the former real/null unknown marker and malformed scalar prefix fallback. Supported extended UTC years now preserve their timestamp.

Fixes #4852
2026-10-19 02:48:09 +08:00
morlutoandMert Kaya 6c98708793 fix(plist): preserve observed non-finite XML reals
Recognize complete CFPropertyList literals at the XML owner and retain
canonical NaN and signed infinity identity as typed scalars. Keep scalar
wrappers distinct from lookalike dictionaries, share limitation text and
document alias normalization. Incomplete markup retains its existing
compatibility fallback and limitation. Bound token matching before case
normalization using the accepted grammar.

Adapted from PR #4908. Fixes #4906.

Validation: public CLI/MCP regression baseline 2 failed, 4 passed.
Final focused validation 430 passed across 25 files, including controlled
entitlement response coverage in the following commit. Real macOS plutil
CLI, check:fast, docs:check and discovery passed. Binary value identity
remains tracked in #4919; malformed literal policy remains #4852.

Co-authored-by: Mert Kaya <47145541+mertkayacs@users.noreply.github.com>
2026-10-18 07:48:18 +08:00
pablodiazjorge 3b5605ecd2 fix(plist): keep negative-zero reals distinct from positive zero (#4839)
Plist inspection reported a serialized -0.0 real as the JSON number 0.
- The shared plist projection reports it as a typed real scalar whose value is the string -0, counted in a limitation for keyed archives and inspect_plist.
- The plutil JSON path applies the same value when it decodes -0.
- The XML decoder no longer returns -0 for a mixed-content integer.

Fixes #4834
2026-10-18 03:56:43 +08:00
morluto 7aa4b98c98 fix(plist): own XML values and numeric facts in one decoder
Interpret the validated, depth-bounded DOM directly. Collect source number
facts during the same traversal and share them with keyed archives, Interface
Builder and native plist projections. Remove the second XML parse, key aliases,
source-location rewriting and both duplicate XML numeric scanners. Preserve
character references, container/null behavior, safe own-property construction
and prototype omission accounting.

Decode signed hexadecimal integers and combine real text/CDATA. Retain exact
integer identity when a finite integer exceeds even Number's finite range,
using the shared scalar projector. Keep unsupported mixed integer syntax
conservative and report incomplete metadata.

Adapt @apitoagents's hexadecimal regression and literal-parsing proposal from
PR #3475. Native plutil controls establish the supported hex/real cases and
confirm that the synthetic 401-digit overflow case exceeds native bounds;
retaining accepted input does not claim native-format support.

Validation: 274 focused checks in 30 files pass, one skipped; build,
check:fast and docs:check pass. Built CLI/actual stdio MCP, native plist and
Interface Builder controls cover kinds, references, exact digits and digests.
Eight baseline checks fail; native binary conversion independently verifies
updated CDATA real expectations. 48 tiny completed CLI cost comparisons
preserve ordinary XML/binary and all three native replies byte for byte.
Two read-only reviews clear. No statistical speed claim, heavy profiler,
investigated-target execution or real deep-provider verification.

Fixes #3373
Fixes #4042
Fixes #4789
2026-10-17 20:40:55 +08:00
morluto 2cf9c28f27 fix(apple): preserve decoded keyed archive scalar identity
Move plist projection into the graph owner and identify generated scalar
wrappers by producer identity through every dictionary/UID consumer. Remove
the intermediate JSON clone that erased those facts. Literal wrapper-shaped
dictionaries remain dictionaries; scalar $top values fail as malformed.
Keep numeric projection after graph interpretation, preserve unknown counts,
and retain binary prototype-key partial facts with an explicit limitation.

Adapt @Jax367's relevant scalar proposal and public regression from PR #4317.
Add scalar-root, literal-root and binary prototype controls. Correct only
the captured Foundation data node expectation and its manifest digest;
original producer bytes and source are unchanged. Unrelated PR changes excluded.

Validation: 175 focused checks across 23 files pass, one skipped; build,
check:fast and docs:check pass. Public CLI and stdio MCP cover both encodings.
Baseline scalar controls fail; 24 tiny completed CLI cost comparisons retain
ordinary full replies and Evidence IDs byte for byte. No statistical speed
claim, heavy profiling, target execution or real deep-provider verification.

Fixes #4295
Fixes #4785
2026-10-17 20:20:53 +08:00
44c9ff7b75 fix(apple): preserve 128-bit keyed archive integers (#4324)
* fix(apple): preserve 128-bit keyed archive integers

* fix(browser): retain cancelled scenario steps

* fix(apple): guard wide plist integer decoding

* test(browser): retain cancellation error contract

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 00:09:47 +08:00
Kaoru0822andClaude Opus 5.5 7a66470385 fix(apple): report plist dates the decoder cannot represent as unknown (#3793)
plutil writes years past 9999 and negative years in a form the pinned
XML decoder cannot parse, and binary plists can hold dates outside the
JavaScript Date range. The decoder returns an Invalid Date. Its
projection's toISOString() call then threw, so inspect_plist failed the
whole plist as "unreadable_output" with a `rea doctor` remediation.
Keyed archive inspection and Interface Builder decoding rejected the
archive in the same way.

projectPlistValue, the shared projection, now reports such a date as
{ "$plist_type": "date", "iso8601": null } and counts it. inspect_plist,
keyed archive inspection and Interface Builder decoding each add a
counted limitation, as they already do for non-finite reals.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:13:01 -07:00
morluto dc038d16bb fix(apple): preserve archive signatures and metadata byte identity 2026-10-13 07:34:52 +08:00
morluto 8d3cfef753 fix(plist): disclose binary prototype-key omissions
Reuse the bounded binary preflight to observe dictionary keys before the pinned decoder drops them. Keyed archive results disclose the omission and Interface Builder marks archive decoding partial. XML keeps its existing exact counts; binary reporting deliberately leaves the count unknown because overwritten subtrees and decoder projection can change visibility.

Remove the superseded size-only preflight contract. Cover ASCII, UTF-16 and extended lengths, shared references, nested and shadowed dictionaries, and the value-only negative control. Synthetic plist and filesystem fixtures; no plutil or ibtool verification.

Fixes #1594. Supersedes #1593.
2026-10-11 07:02:39 +08:00
morluto 6d4cefc4f7 fix(artifacts): admit bounded reads and preserve source identity
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:18 +08:00
Rudy Celekli c8fd2f152b fix(apple): scope keyed archive traversal to the selection
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 21:17:35 +08:00
Kaoru0822andClaude Opus 5.5 2bf812772d fix(apple): bound binary plist expansion before decoding keyed archives (#1515)
inspect_keyed_archive passed caller-selected binary plists straight to
plist.parseBinary, which recurses on every object reference and copies
shared containers. A 484-byte archive of forty nested [next, next] arrays
grew the process past 4 GB until it died with no result, which would also
end an MCP server. A 125-byte self-referencing array overflowed the stack
and was reported as an artifact too large to process.

The iterative reference walk that already guards decode_interface_builder
now runs first, with an 8x keyed-archive decode budget. Over-budget depth
or expansion is a limit; a reference cycle is a malformed archive. Its
"decoder" bounds admit the same layouts plist.parseBinary reads, so
accepted archives stay accepted. Interface Builder behavior is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:44:46 -07:00
morluto 5751f5caac fix(artifacts): preserve archive facts and Unicode path identity 2026-10-10 05:13:53 +08:00
Kaoru0822andClaude Opus 5.5 22958558ea fix(artifacts): name only host-available workflows for non-archive plists
inspect_keyed_archive runs on every host, but its remediation for an
ordinary property list pointed to inspect_plist, which only macOS
supports. On Linux that sent callers to a workflow the capability layer
rejects.

The domain error now names what the file is. The artifact reader picks
the remediation from the provider's host: inspect_plist on macOS, and
elsewhere the selection of an NSKeyedArchiver archive, with a note that
inspect_plist requires macOS. decode_interface_builder, which is
portable, stays the NIBArchive remediation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:40:45 +00:00
Kaoru0822andClaude Opus 5.5 8c5088c8cd fix(artifacts): report non-archive keyed-archive selections as unsupported targets
inspect_keyed_archive reported a selected ordinary property list or a
compiled NIBArchive as a damaged artifact: "Artifact is invalid or has
changed. Get a fresh copy and try again." The file is intact; it is
another kind of file, and the workflow that reads it (inspect_plist or
decode_interface_builder) appeared only in details.detail.

Report a NIBArchive, or a plist whose $archiver is not NSKeyedArchiver,
as unsupported_target with that workflow as the remediation. An
NSKeyedArchiver archive that fails to decode stays a format failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:28:21 +00:00
morlutoandRudy Mizrahi Celekli 4034883e98 fix(artifacts): preserve keyed archive integer precision
Integrate the numeric precision correction from #1135 with complete supplemental
metadata handling. Keep decoded numbers with an explicit limitation for mixed XML
content or unclassified integer text, rather than assigning another literal's
exact decimal. Project nonnumeric UID and CF$UID dictionary values recursively
while preserving numeric references, graph identity and original byte digests.

Add filesystem, built CLI and MCP regressions for the review findings, adjacent
XML representations and numeric reference controls. Retain the original native
Foundation qualification fixtures and verifier.

Verification: 84 focused tests; npm run check; npm run docs:check;
npm run verify:test-discovery; npm run verify:keyed-archive (real Foundation,
CLI and stdio MCP). No real Hopper or Ghidra verification was needed or run.

Co-authored-by: Rudy Mizrahi Celekli <47457359+rudycelekli@users.noreply.github.com>
Signed-off-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 07:13:32 +08:00
morluto d575a7340b fix(apple): decode bundle plist bytes before executable lookup 2026-10-09 06:32:09 +08:00
Rudy Mizrahi CelekliandN0zoM1z0 f8e143a3bc fix(apple): decode Interface Builder XML byte encodings (#1095)
* test(apple): qualify native Interface Builder XML encodings

Exercise actual AppKit/Foundation XML archive representations through filesystem and compiled CLI consumers. Preserve independent UID/hierarchy and original-byte provenance oracles.

Tests-only candidate qualification on unchanged native Apple CI; no production or workflow changes.

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

* fix(apple): share BOM-aware Interface Builder XML decoding

Reuse the existing fatal BOM-aware XML plist decoder for Interface Builder archives. Preserve original serialized-byte digests, binary decoding, and frozen native producer/consumer tests.

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>

* fix(apple): reject unsupported XML encoding declarations

---------

Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-09 01:11:49 +08:00
Kaoru0822andClaude Opus 5.5 25fb6d32a3 fix(artifacts): report keyed-archive selection mistakes as invalid input
inspect_keyed_archive reported caller selection failures as artifact
faults. A missing named root became "Artifact is invalid or has changed.
Get a fresh copy" and lost its reason, and a missing, non-canonical, or
directory archive path became "unsafe or conflicting internal path ...
correct the artifact".

Report these as invalid_request issues on `path` or `root`, listing the
available $top roots or the active plist basename. Decode failures keep
the decoder's reason, and a compiled NIBArchive points to
decode_interface_builder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:43:30 +00:00
ysopwnable ef1a0cc65a refactor(apple): group artifact producers and verification (#952)
* refactor(apple): group artifact producers and verification

* test(apple): run affected native plist CLI regressions
2026-10-07 21:09:33 +08:00