Commit Graph
18 Commits
Author SHA1 Message Date
morluto e1df5e8555 fix(apple): account for repeated archive projections 2026-10-09 06:32:10 +08:00
morluto dbcf8c3391 fix(apple): budget Interface Builder decoding and projection 2026-10-09 05:15:23 +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
morluto 71ac83f3dd fix(apple): traverse keyed archive hierarchy collections (#976) 2026-10-07 23:00:43 +08: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
Kaoru0822 aa8082ea6c Merge pull request #913 from morluto/fix/uikit-runtime-connections
fix(artifacts): project UIKit runtime outlet and event connections
2026-10-07 04:00:25 -07:00
morluto 1d769cd261 chore: merge main and preserve UIKit and AppKit connections 2026-10-07 18:02:05 +08:00
morluto 071cfd1bb6 chore: merge main and preserve plist and AppKit regressions 2026-10-07 18:02:05 +08:00
Kaoru0822andClaude Opus 5.5 900d7c8606 fix(artifacts): project compiled AppKit actions from the control to its target (#905)
* fix(artifacts): project compiled AppKit actions from the control to its target

NSNibControlConnector archives the sending control as NSSource and the
action target as NSDestination; a nil target is the first responder. The
NIBArchive projection swapped them for control connectors, so every
compiled AppKit action ran from its target to the control. The action
trace, which follows control -> action, could not find them, and the
selector node was keyed by the control instead of the target class. When
the target was nil, the swapped source was null and the action was
dropped: Chess lost 29 menu actions, KeepingYouAwake 7.

Connectors now keep NSSource -> NSDestination. The NIBArchive test
encoder moves to a fixture module so a bundle test can build compiled
NIBs.

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

* test(artifacts): report observed action routes when a compiled route is missing

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

* test(artifacts): report compiled connector records when a storyboard route is missing

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

* test(artifacts): write the storyboard fixture's action in Cocoa syntax

MacFixture.storyboard declared its button action with the iOS attribute,
<action selector="buildTapped:" destination="vc1">. Cocoa documents
name an action's receiver with target=. ibtool compiled the iOS spelling
into an NSNibControlConnector whose NSSource is the view controller
placeholder and whose NSDestination is the button. That is the reverse
of what Xcode-authored AppKit NIBs contain (Music, Chess,
KeepingYouAwake, and Transmission all archive NSSource as the control),
and it is what the old inversion had matched. With target= the compiled
fixture archives the button as NSSource. The temporary connector dump is
removed; the observed routes remain in the assertion message.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:40:18 +08:00
morluto 96a9f32dc1 chore: merge main and resolve PR #899 conflicts 2026-10-07 17:28:55 +08:00
Kaoru0822andClaude Opus 5.5 8b243877c2 fix(artifacts): project UIKit runtime outlet and event connections
Compiled UIKit NIBs and storyboards archive outlets and control actions
as UIRuntimeOutletConnection and UIRuntimeEventConnection with
UISource, UIDestination, and UILabel. The NIBArchive projection
recognized only AppKit *Connector classes with NS-prefixed keys, so an
iOS app produced no outlet or action edges: Stash's 64 decoded documents
yielded none. These connections are now projected with the same
source -> destination roles, an event connection carries its
UIEventMask as ui_event_mask, UIClassSwapper reports its UIClassName,
UIProxyObject is a placeholder, and connection records are no longer
emitted as unknown objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:10:53 +00:00
Kaoru0822andClaude Opus 5.5 53bfa7e3f7 test(artifacts): write the storyboard fixture's action in Cocoa syntax
MacFixture.storyboard declared its button action with the iOS attribute,
<action selector="buildTapped:" destination="vc1">. Cocoa documents
name an action's receiver with target=. ibtool compiled the iOS spelling
into an NSNibControlConnector whose NSSource is the view controller
placeholder and whose NSDestination is the button. That is the reverse
of what Xcode-authored AppKit NIBs contain (Music, Chess,
KeepingYouAwake, and Transmission all archive NSSource as the control),
and it is what the old inversion had matched. With target= the compiled
fixture archives the button as NSSource. The temporary connector dump is
removed; the observed routes remain in the assertion message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:06:36 +00:00
Kaoru0822andClaude Opus 5.5 d421d3f286 test(artifacts): report compiled connector records when a storyboard route is missing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:00:41 +00:00
Kaoru0822andClaude Opus 5.5 c60b737f7d test(artifacts): report observed action routes when a compiled route is missing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 08:46:57 +00:00
Kaoru0822andClaude Opus 5.5 b08228d19f fix(artifacts): project compiled AppKit actions from the control to its target
NSNibControlConnector archives the sending control as NSSource and the
action target as NSDestination; a nil target is the first responder. The
NIBArchive projection swapped them for control connectors, so every
compiled AppKit action ran from its target to the control. The action
trace, which follows control -> action, could not find them, and the
selector node was keyed by the control instead of the target class. When
the target was nil, the swapped source was null and the action was
dropped: Chess lost 29 menu actions, KeepingYouAwake 7.

Connectors now keep NSSource -> NSDestination. The NIBArchive test
encoder moves to a fixture module so a bundle test can build compiled
NIBs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 08:39:27 +00:00
Kaoru0822andClaude Opus 5.5 2a4667bb79 fix(artifacts): decode flat keyed-archive NIBs with data and shared references
decode_interface_builder failed on every flat (keyed-archive) NIB that
holds plist data or dates. Archived colors keep their components as
data, so this covers nearly every AppKit NIB: XLD.app decoded 0 of 64.
The decoded Uint8Array and Date values failed JSON validation. They now
use the shared plist projection, which keeps them as explicit
$plist_type values.

Decoding those archives exposed a second failure. The keyed-archive
parser inlined every UID reference up to 16 levels for every object, so
an archive whose views reference their window, superview, and next key
view expanded exponentially. A 9 KB NIB took 3 s, and a 158 KB
MainMenu.nib did not finish. A reference now resolves to its string, or
to a stub naming the referenced object's archive UID, authored ID, and
class. The hierarchy walk visits each object once. The parser also reads
XML CF$UID references and treats UID 0 as nil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 08:10:25 +00:00
Kaoru0822andClaude Opus 5.5 6729ee7636 fix(plist): report omitted __proto__ entries in signatures and Interface Builder
#885 decodes XML plists that contain a __proto__ key by omitting those
entries, but signature entitlements and Interface Builder plists dropped
the omission count. inspect_signature returned an entitlement set that
looked complete, and archive_decode stayed complete. Both now report the
omission: a signature limitation, and a partial archive_decode facet with
reason dictionary_entries_omitted and a per-document limitation.

The placeholder that stands in for __proto__ was reserved against the raw
XML text, so an entity-encoded key such as &#95;&#95;rea_prototype_key__
decoded to the placeholder and was omitted as if it were __proto__. The
placeholder is now reserved against the decoded text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 07:51:37 +00:00
morluto f72931d9dd test: eliminate fixture races and prune redundant scaffolding (#849)
* test: eliminate fixture races and prune redundant scaffolding

* fix(test): publish launcher capture readiness without renaming
2026-10-07 12:25:37 +08:00