[GH-ISSUE #5739] [Bug] Compiled storyboard prototype-cell contents are omitted with complete coverage #3486

Closed
opened 2026-10-31 00:41:01 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 21, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5739

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

decode-interface-builder omits the custom cell, content view, label and outlet stored in a compiled table storyboard's embedded prototype nib. The two outer documents report complete object, connection and archive coverage with zero omissions. The same retained prototype bytes decode successfully as a standalone nib in a separate inert app; a static-table control also exposes the cell facts.

Reproduction

Run from a built source checkout with locked dependencies on macOS with Xcode's iOS platform, ibtool, clang, Python 3 and jq. These commands compile and inspect an inert app without launching it. An independent verifier reproduced the prototype three times and the extracted-payload control twice at the baseline. Submission replayed both once after building the fetched main revision below.

work_dir="$(mktemp -d)"
mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" "$work_dir/cache" \
  "$work_dir/state" "$work_dir/tmp" \
  "$work_dir/Proto.app/Contents/MacOS" "$work_dir/Proto.app/Contents/Resources"
cat > "$work_dir/Proto.storyboard" <<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="list-1">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23094"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <scene sceneID="list-scene">
            <objects>
                <tableViewController id="list-1" customClass="ListViewController" customModule="Proto" customModuleProvider="target" sceneMemberID="viewController">
                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" dataMode="prototypes" style="plain" id="table-1">
                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <prototypes>
                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" reuseIdentifier="RowCell" id="cell-1" customClass="RowCell" customModule="Proto" customModuleProvider="target">
                                <rect key="frame" x="0.0" y="50" width="393" height="44"/>
                                <autoresizingMask key="autoresizingMask"/>
                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" contentMode="center" tableViewCell="cell-1" id="cell-content">
                                    <rect key="frame" x="0.0" y="0.0" width="393" height="44"/>
                                    <autoresizingMask key="autoresizingMask"/>
                                    <subviews>
                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Row" id="cell-label">
                                            <rect key="frame" x="20" y="11" width="200" height="21"/>
                                        </label>
                                    </subviews>
                                </tableViewCellContentView>
                                <connections>
                                    <outlet property="titleLabel" destination="cell-label" id="cell-out"/>
                                </connections>
                            </tableViewCell>
                        </prototypes>
                    </tableView>
                </tableViewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="list-fr" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>
</document>
XML
xcrun ibtool --errors --warnings \
  --compile "$work_dir/Proto.app/Contents/Resources/Proto.storyboardc" \
  "$work_dir/Proto.storyboard" --target-device iphone \
  --minimum-deployment-target 17.0 > "$work_dir/compile.plist"
printf 'int main(void){return 0;}\n' > "$work_dir/proto.c"
xcrun clang "$work_dir/proto.c" -o "$work_dir/Proto.app/Contents/MacOS/Proto"
cat > "$work_dir/Proto.app/Contents/Info.plist" <<'XML'
<?xml version="1.0"?>
<plist version="1.0"><dict><key>CFBundleExecutable</key><string>Proto</string><key>CFBundleIdentifier</key><string>dev.rea.proto</string></dict></plist>
XML
xcrun ibtool --objects --connections --hierarchy --output-format xml1 \
  "$work_dir/Proto.storyboard" > "$work_dir/oracle.plist"
env -i PATH="$PATH" HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/cfg" \
  XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \
  XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \
  node scripts/rea.mjs decode-interface-builder "$work_dir/Proto.app" --json \
  > "$work_dir/out.json"
jq '{documents: .normalized_result.documents,
     classes: [.normalized_result.graph.nodes[].attributes.class_name // empty] | unique,
     outlets: [.normalized_result.graph.nodes[] | select(.kind == "outlet") | .attributes.label],
     coverage: [.normalized_result.graph.coverage[]
       | select(.facet | test("objects:|connections:|archive_decode"))]}' "$work_dir/out.json"
python3 - "$work_dir/oracle.plist" <<'PY_ORACLE'
import plistlib, sys
with open(sys.argv[1], "rb") as stream:
    oracle = plistlib.load(stream)
objects = oracle["com.apple.ibtool.document.objects"]
for key in ["cell-1", "cell-content", "cell-label"]:
    print(key, objects[key]["class"], objects[key].get("custom-class"))
print(oracle["com.apple.ibtool.document.connections"])
PY_ORACLE

Extract the retained prototype bytes and inspect them in a separate inert app:

python3 - "$work_dir" <<'PY_EXTRACT'
import base64, json, shutil, sys
from pathlib import Path
work = Path(sys.argv[1])
app = work / "Extracted.app"
(app / "Contents/MacOS").mkdir(parents=True)
(app / "Contents/Resources").mkdir(parents=True)
shutil.copy2(work / "Proto.app/Contents/Info.plist", app / "Contents/Info.plist")
shutil.copy2(work / "Proto.app/Contents/MacOS/Proto", app / "Contents/MacOS/Proto")
result = json.loads((work / "out.json").read_text())["normalized_result"]
data = next(node for node in result["graph"]["nodes"]
            if node["attributes"].get("class_name") == "NSData")
encoded = data["attributes"]["nibValues"]["NS.bytes"]["$nib_data_base64"]
payload = base64.b64decode(encoded)
print(len(payload), payload[:10])
(app / "Contents/Resources/Cell.nib").write_bytes(payload)
PY_EXTRACT
env -i PATH="$PATH" HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/cfg" \
  XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \
  XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \
  node scripts/rea.mjs decode-interface-builder "$work_dir/Extracted.app" --json \
  > "$work_dir/extracted.json"
jq '{documents: .normalized_result.documents,
     classes: [.normalized_result.graph.nodes[].attributes.class_name // empty] | unique,
     outlets: [.normalized_result.graph.nodes[] | select(.kind == "outlet") | .attributes.label]}' \
  "$work_dir/extracted.json"

A static-table control was also executed once at each tested revision: change dataMode="prototypes" to dataMode="static", replace <prototypes> with <sections><tableViewSection id="section-1"><cells>, and replace </prototypes> with </cells></tableViewSection></sections>. Compile into a separate app and decode with the same isolated runner.

Expected behavior

Represent the serialized cell objects, custom class and outlet in the containing graph or a distinct nested document. If embedded prototype archives are unsupported, disclose this specific omission and make the affected completeness facets reflect it. A generic private-fields limitation does not identify the missing prototype archive.

Contract sources at the baseline: src/contracts/artifactToolContracts.ts:92-96 advertises static compiled storyboard/nib object, hierarchy and connection decoding; docs/native-investigation.md:386-398 includes objects, outlets and class names with explicit unsupported archive forms; docs/tool-design.md:171-176 requires completeness derived from examined records and exhaustiveness. The source oracle and successful standalone decode establish that these facts are serialized and recoverable.

Impact and scope

P2: meaningful cell-class, object and outlet evidence is absent while coverage claims completeness for this supported compiled table storyboard. The demonstrated workaround recovers cell facts by saving retained NSData bytes as a standalone nib in a separate inert app and decoding it; this is manual and produces a separate graph rather than restoring the original prototype relationship. No target launch, data mutation or security impact occurred. Collection-view prototypes, constraints loss, shipping-app prevalence and MCP transport were not tested.

REA version

rea-agents 6.7.0; independently verified baseline 9d8e7803326a382cbbb3ffdb900f5e93e5442d68. Rechecked after npm run build:cached at fetched origin/main d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f (also 6.7.0): still reproduces. These are source-checkout observations.

Runtime and platform

Node.js v26.12.0; macOS 27.0.1 arm64; Xcode 27.1 (27A9275), ibtool 27.1 (25098). No optional analysis provider involved.

Target and artifact context

Self-built Mach-O app bundles containing an ibtool-compiled UIKit table storyboard, minimum iOS deployment target 17.0. HOME/XDG/TMPDIR are isolated. The app is inspected without launching it or instantiating UIKit objects.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Compilation has no errors or warnings; prototype and extracted-payload CLI calls exit 0 with empty stderr. The results agree at both tested revisions:

Prototype documents: objects/connections = 4/2 and 5/1
Classes: NSData, UINib, UIProxyObject, UITableView, _TtC5Proto18ListViewController
Outlets: sceneViewController, storyboard, view
All objects/connections facets: status complete, omitted 0, reason null
archive_decode: status complete, examined 2, omitted 0, reason null
Both hierarchy facets: unsupported (no false complete-hierarchy claim)

ibtool --objects --connections --hierarchy on the source identifies cell-1 as IBUITableViewCell with authored class _TtC5Proto7RowCell, cell-content as IBUITableViewCellContentView, cell-label as IBUILabel, and titleLabel from cell-1 to cell-label.

The outer result retains UINib.archiveData referencing an NSData object with a 3,864-byte payload beginning NIBArchive. Standalone decoding returns 14 objects and one connection, including _TtC5Proto7RowCell, UITableViewCellContentView, UILabel and titleLabel. The static-table control returns 18 objects and three connections in its view document, including the same cell facts. Evidence provenance: observed; local verification: independently reproduced and replayed on main.

Typed outcome or recovery expected

Proposed restoration check: retain the prototype's serialized custom cell, content view, label and titleLabel, or explicitly identify the unsupported nested prototype and prevent misleading complete object, connection and archive coverage. Preserve the static-table and standalone-payload controls. Do not remove the embedded nib or convert the prototype to a static table to satisfy the check. No particular parser strategy or internal representation is required.

Analysis or suspected cause

Source-derived reasoning at the baseline: src/artifacts/apple/InterfaceBuilderAnalysis.ts:95-137,187-199,239-245 selects and projects outer files once; :455-478 retains binary data and references without decoding the recognized embedded UINib.archiveData payload; :493-565 projects outer records. src/domain/apple/interfaceBuilderGraph.ts:493-530 derives object/connection coverage from those projected records, and InterfaceBuilderAnalysis.ts:338-359 adds archive coverage for outer files. Main retains this behavior; intervening changes add resource-root metadata rather than nested-archive decoding. No bundled dependency was identified as the cause.

Additional context

Prepared with AI assistance and independent verification. Sibling #5692 concerns outlet-collection endpoint membership; #5693 (including its nested-descendant comment) concerns hierarchy paths for already retained objects; #5695 concerns segue admission; #5720 concerns false control classification; #5721 concerns keyed placeholder class identity. Their fixes can leave this nested archive's objects and outlet absent. This report does not claim missing top-level hierarchy membership.

Merged #913 restores UIKit outlets in archives already selected for decoding; the standalone control demonstrates that path works here. Open #3502's repeated-key array note does not address recursively decoding a one-cell embedded payload. Closed #3958 / merged #4118 concern dangling keyed-archive class references, absent from this compiled NIBArchive fixture. These are related reports, not the same restoration signal.

NOT_ENOUGH_INFO: no earlier known-good revision or regression introduction was established. No fix or restoration was tested.

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5739 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `decode-interface-builder` omits the custom cell, content view, label and outlet stored in a compiled table storyboard's embedded prototype nib. The two outer documents report complete object, connection and archive coverage with zero omissions. The same retained prototype bytes decode successfully as a standalone nib in a separate inert app; a static-table control also exposes the cell facts. ### Reproduction Run from a built source checkout with locked dependencies on macOS with Xcode's iOS platform, ibtool, clang, Python 3 and jq. These commands compile and inspect an inert app without launching it. An independent verifier reproduced the prototype three times and the extracted-payload control twice at the baseline. Submission replayed both once after building the fetched main revision below. ```sh work_dir="$(mktemp -d)" mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" "$work_dir/cache" \ "$work_dir/state" "$work_dir/tmp" \ "$work_dir/Proto.app/Contents/MacOS" "$work_dir/Proto.app/Contents/Resources" cat > "$work_dir/Proto.storyboard" <<'XML' <?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="list-1"> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23094"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> <scene sceneID="list-scene"> <objects> <tableViewController id="list-1" customClass="ListViewController" customModule="Proto" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" dataMode="prototypes" style="plain" id="table-1"> <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <prototypes> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" reuseIdentifier="RowCell" id="cell-1" customClass="RowCell" customModule="Proto" customModuleProvider="target"> <rect key="frame" x="0.0" y="50" width="393" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" contentMode="center" tableViewCell="cell-1" id="cell-content"> <rect key="frame" x="0.0" y="0.0" width="393" height="44"/> <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Row" id="cell-label"> <rect key="frame" x="20" y="11" width="200" height="21"/> </label> </subviews> </tableViewCellContentView> <connections> <outlet property="titleLabel" destination="cell-label" id="cell-out"/> </connections> </tableViewCell> </prototypes> </tableView> </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="list-fr" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> </objects> </scene> </scenes> </document> XML xcrun ibtool --errors --warnings \ --compile "$work_dir/Proto.app/Contents/Resources/Proto.storyboardc" \ "$work_dir/Proto.storyboard" --target-device iphone \ --minimum-deployment-target 17.0 > "$work_dir/compile.plist" printf 'int main(void){return 0;}\n' > "$work_dir/proto.c" xcrun clang "$work_dir/proto.c" -o "$work_dir/Proto.app/Contents/MacOS/Proto" cat > "$work_dir/Proto.app/Contents/Info.plist" <<'XML' <?xml version="1.0"?> <plist version="1.0"><dict><key>CFBundleExecutable</key><string>Proto</string><key>CFBundleIdentifier</key><string>dev.rea.proto</string></dict></plist> XML xcrun ibtool --objects --connections --hierarchy --output-format xml1 \ "$work_dir/Proto.storyboard" > "$work_dir/oracle.plist" env -i PATH="$PATH" HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/cfg" \ XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \ XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \ node scripts/rea.mjs decode-interface-builder "$work_dir/Proto.app" --json \ > "$work_dir/out.json" jq '{documents: .normalized_result.documents, classes: [.normalized_result.graph.nodes[].attributes.class_name // empty] | unique, outlets: [.normalized_result.graph.nodes[] | select(.kind == "outlet") | .attributes.label], coverage: [.normalized_result.graph.coverage[] | select(.facet | test("objects:|connections:|archive_decode"))]}' "$work_dir/out.json" python3 - "$work_dir/oracle.plist" <<'PY_ORACLE' import plistlib, sys with open(sys.argv[1], "rb") as stream: oracle = plistlib.load(stream) objects = oracle["com.apple.ibtool.document.objects"] for key in ["cell-1", "cell-content", "cell-label"]: print(key, objects[key]["class"], objects[key].get("custom-class")) print(oracle["com.apple.ibtool.document.connections"]) PY_ORACLE ``` Extract the retained prototype bytes and inspect them in a separate inert app: ```sh python3 - "$work_dir" <<'PY_EXTRACT' import base64, json, shutil, sys from pathlib import Path work = Path(sys.argv[1]) app = work / "Extracted.app" (app / "Contents/MacOS").mkdir(parents=True) (app / "Contents/Resources").mkdir(parents=True) shutil.copy2(work / "Proto.app/Contents/Info.plist", app / "Contents/Info.plist") shutil.copy2(work / "Proto.app/Contents/MacOS/Proto", app / "Contents/MacOS/Proto") result = json.loads((work / "out.json").read_text())["normalized_result"] data = next(node for node in result["graph"]["nodes"] if node["attributes"].get("class_name") == "NSData") encoded = data["attributes"]["nibValues"]["NS.bytes"]["$nib_data_base64"] payload = base64.b64decode(encoded) print(len(payload), payload[:10]) (app / "Contents/Resources/Cell.nib").write_bytes(payload) PY_EXTRACT env -i PATH="$PATH" HOME="$work_dir/home" XDG_CONFIG_HOME="$work_dir/cfg" \ XDG_DATA_HOME="$work_dir/data" XDG_CACHE_HOME="$work_dir/cache" \ XDG_STATE_HOME="$work_dir/state" TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \ node scripts/rea.mjs decode-interface-builder "$work_dir/Extracted.app" --json \ > "$work_dir/extracted.json" jq '{documents: .normalized_result.documents, classes: [.normalized_result.graph.nodes[].attributes.class_name // empty] | unique, outlets: [.normalized_result.graph.nodes[] | select(.kind == "outlet") | .attributes.label]}' \ "$work_dir/extracted.json" ``` A static-table control was also executed once at each tested revision: change `dataMode="prototypes"` to `dataMode="static"`, replace `<prototypes>` with `<sections><tableViewSection id="section-1"><cells>`, and replace `</prototypes>` with `</cells></tableViewSection></sections>`. Compile into a separate app and decode with the same isolated runner. ### Expected behavior Represent the serialized cell objects, custom class and outlet in the containing graph or a distinct nested document. If embedded prototype archives are unsupported, disclose this specific omission and make the affected completeness facets reflect it. A generic private-fields limitation does not identify the missing prototype archive. Contract sources at the baseline: `src/contracts/artifactToolContracts.ts:92-96` advertises static compiled storyboard/nib object, hierarchy and connection decoding; `docs/native-investigation.md:386-398` includes objects, outlets and class names with explicit unsupported archive forms; `docs/tool-design.md:171-176` requires completeness derived from examined records and exhaustiveness. The source oracle and successful standalone decode establish that these facts are serialized and recoverable. ### Impact and scope P2: meaningful cell-class, object and outlet evidence is absent while coverage claims completeness for this supported compiled table storyboard. The demonstrated workaround recovers cell facts by saving retained NSData bytes as a standalone nib in a separate inert app and decoding it; this is manual and produces a separate graph rather than restoring the original prototype relationship. No target launch, data mutation or security impact occurred. Collection-view prototypes, constraints loss, shipping-app prevalence and MCP transport were not tested. ### REA version `rea-agents` 6.7.0; independently verified baseline `9d8e7803326a382cbbb3ffdb900f5e93e5442d68`. Rechecked after `npm run build:cached` at fetched `origin/main` `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f` (also 6.7.0): still reproduces. These are source-checkout observations. ### Runtime and platform Node.js v26.12.0; macOS 27.0.1 arm64; Xcode 27.1 (27A9275), ibtool 27.1 (25098). No optional analysis provider involved. ### Target and artifact context Self-built Mach-O app bundles containing an ibtool-compiled UIKit table storyboard, minimum iOS deployment target 17.0. HOME/XDG/TMPDIR are isolated. The app is inspected without launching it or instantiating UIKit objects. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Compilation has no errors or warnings; prototype and extracted-payload CLI calls exit 0 with empty stderr. The results agree at both tested revisions: ```text Prototype documents: objects/connections = 4/2 and 5/1 Classes: NSData, UINib, UIProxyObject, UITableView, _TtC5Proto18ListViewController Outlets: sceneViewController, storyboard, view All objects/connections facets: status complete, omitted 0, reason null archive_decode: status complete, examined 2, omitted 0, reason null Both hierarchy facets: unsupported (no false complete-hierarchy claim) ``` `ibtool --objects --connections --hierarchy` on the source identifies `cell-1` as `IBUITableViewCell` with authored class `_TtC5Proto7RowCell`, `cell-content` as `IBUITableViewCellContentView`, `cell-label` as `IBUILabel`, and `titleLabel` from `cell-1` to `cell-label`. The outer result retains `UINib.archiveData` referencing an `NSData` object with a 3,864-byte payload beginning `NIBArchive`. Standalone decoding returns 14 objects and one connection, including `_TtC5Proto7RowCell`, `UITableViewCellContentView`, `UILabel` and `titleLabel`. The static-table control returns 18 objects and three connections in its view document, including the same cell facts. Evidence provenance: observed; local verification: independently reproduced and replayed on main. ### Typed outcome or recovery expected Proposed restoration check: retain the prototype's serialized custom cell, content view, label and `titleLabel`, or explicitly identify the unsupported nested prototype and prevent misleading complete object, connection and archive coverage. Preserve the static-table and standalone-payload controls. Do not remove the embedded nib or convert the prototype to a static table to satisfy the check. No particular parser strategy or internal representation is required. ### Analysis or suspected cause Source-derived reasoning at the baseline: `src/artifacts/apple/InterfaceBuilderAnalysis.ts:95-137,187-199,239-245` selects and projects outer files once; `:455-478` retains binary data and references without decoding the recognized embedded `UINib.archiveData` payload; `:493-565` projects outer records. `src/domain/apple/interfaceBuilderGraph.ts:493-530` derives object/connection coverage from those projected records, and `InterfaceBuilderAnalysis.ts:338-359` adds archive coverage for outer files. Main retains this behavior; intervening changes add resource-root metadata rather than nested-archive decoding. No bundled dependency was identified as the cause. ### Additional context Prepared with AI assistance and independent verification. Sibling #5692 concerns outlet-collection endpoint membership; #5693 (including its nested-descendant comment) concerns hierarchy paths for already retained objects; #5695 concerns segue admission; #5720 concerns false control classification; #5721 concerns keyed placeholder class identity. Their fixes can leave this nested archive's objects and outlet absent. This report does not claim missing top-level hierarchy membership. Merged #913 restores UIKit outlets in archives already selected for decoding; the standalone control demonstrates that path works here. Open #3502's repeated-key array note does not address recursively decoding a one-cell embedded payload. Closed #3958 / merged #4118 concern dangling keyed-archive class references, absent from this compiled NIBArchive fixture. These are related reports, not the same restoration signal. NOT_ENOUGH_INFO: no earlier known-good revision or regression introduction was established. No fix or restoration was tested.
Author
Owner

@XinwangTao commented on GitHub (Oct 21, 2026):

Confirmed: the contradiction between "complete coverage" in the two outer documents and the missing cell/content-view/label/outlet is the key diagnostic signal — the embedded prototype nib clearly falls outside the decode traversal even though the identical bytes parse fine as a standalone nib. That strongly suggests decode-interface-builder walks the compiled storyboard's object/connection archives but never descends into embedded prototype nib payloads, so coverage accounting reports completeness over a smaller domain than the artifact actually contains.

Suggestions: (1) treat each embedded nib as its own coverage target so "complete coverage" cannot mask the omission; (2) add a regression fixture with a table storyboard whose prototype nib carries custom cell facts, asserting the cell, content view, label and outlet all appear; (3) check whether the same gap exists for collection-view prototype cells and for embedded nibs referenced from other compiled archives, since they share the same embedding mechanism.

<!-- gh-comment-id:6305626083 --> @XinwangTao commented on GitHub (Oct 21, 2026): Confirmed: the contradiction between "complete coverage" in the two outer documents and the missing cell/content-view/label/outlet is the key diagnostic signal — the embedded prototype nib clearly falls outside the decode traversal even though the identical bytes parse fine as a standalone nib. That strongly suggests decode-interface-builder walks the compiled storyboard's object/connection archives but never descends into embedded prototype nib payloads, so coverage accounting reports completeness over a smaller domain than the artifact actually contains. Suggestions: (1) treat each embedded nib as its own coverage target so "complete coverage" cannot mask the omission; (2) add a regression fixture with a table storyboard whose prototype nib carries custom cell facts, asserting the cell, content view, label and outlet all appear; (3) check whether the same gap exists for collection-view prototype cells and for embedded nibs referenced from other compiled archives, since they share the same embedding mechanism.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3486
No description provided.