[GH-ISSUE #6066] [Bug] Interface Builder decoding treats read and identity failures as invalid archives #3706

Closed
opened 2026-10-31 00:43:15 +00:00 by bsakaguchi · 0 comments
Owner

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

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 exits successfully when a selected readable-format nib cannot be opened due to EACCES. It returns no decoded documents, graph.truncated: true, and archive coverage reason one_or_more_archives_invalid. The read error survives only as a limitation describing an archive that could not be decoded.

A separate production MCP test replaces a document with byte-identical new-inode content after selection. The actual reader throws ArtifactReaderFailure reason integrity, but the tool also returns successful Evidence with the same invalid-archive coverage. Restoring the original input restores the exact control graph.

Reproduction

Two executions isolate permission and identity failures.

For the real permission denial, save this executed CLI driver outside a prepared checkout as ib-permission-reproduction.mjs, set REPRO_ROOT to an existing disposable writable directory outside the checkout, then run it from the checkout using node ib-permission-reproduction.mjs. Run as a non-root POSIX user.

import { mkdir, mkdtemp, writeFile, chmod, readFile, rm } from 'node:fs/promises';
import { join } from 'node:path';
import { spawnSync } from 'node:child_process';
import assert from 'node:assert/strict';
const root = await mkdtemp(join(process.env.REPRO_ROOT, 'permission-case-'));
const app = join(root, 'Fixture.app');
const resources = join(app, 'Contents', 'Resources');
await mkdir(resources, { recursive: true });
await writeFile(join(app, 'Contents', 'Info.plist'), '<plist><dict><key>CFBundleIdentifier</key><string>org.example.fixture</string></dict></plist>');
const env = { ...process.env, REA_LOG_LEVEL: 'silent' };
for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_STATE_HOME', 'TMPDIR']) {
  env[key] = join(root, key.toLowerCase());
  await mkdir(env[key]);
}
const path = join(resources, 'Main.nib');
await writeFile(path, '<plist><dict><key>com.apple.ibtool.document.objects</key><dict><key>button</key><dict><key>customClass</key><string>NSButton</string><key>label</key><string>Build</string></dict></dict></dict></plist>');
const args = ['scripts/rea.mjs', 'decode-interface-builder', app, '--json'];
const run = (label) => {
  const child = spawnSync(process.execPath, args, { env, encoding: 'utf8', timeout: 45000 });
  if (child.error) throw child.error;
  assert.equal(child.stderr, '');
  const output = JSON.parse(child.stdout);
  const result = output.normalized_result ?? output;
  console.log(JSON.stringify({ label, exit: child.status, result }).replaceAll(root, '<fixture-root>'));
  return { exit: child.status, result };
};
try {
  const control = run('readable');
  assert.equal(control.exit, 0);
  await chmod(path, 0);
  await assert.rejects(readFile(path), { code: 'EACCES' });
  const denied = run('denied');
  assert.equal(denied.exit, 0);
  assert.deepEqual(denied.result.documents, []);
  assert(denied.result.graph.coverage.some(x => x.facet === 'archive_decode' && x.reason === 'one_or_more_archives_invalid'));
  assert(denied.result.limitations.some(x => x.includes('EACCES')));
  await chmod(path, 0o600);
  const restored = run('restored');
  assert.equal(restored.exit, 0);
  assert.deepEqual(restored.result.graph.nodes, control.result.graph.nodes);
} finally {
  await chmod(path, 0o600);
  await rm(root, { recursive: true, force: true });
}

For the controlled identity change, save the following executed focused test as tests/process-global/interfaceBuilderReadFailure.test.ts and run node node_modules/vitest/vitest.mjs run tests/process-global/interfaceBuilderReadFailure.test.ts --maxWorkers=1 with REPRO_ROOT set as above. The wrapper changes only timing: it replaces the fixture just before the real reader opens the enumerated entry. No filesystem errors, filesystem implementation, parser, provider or projection are simulated. The test characterizes the faulty behavior and therefore passes while it is present.

import { Client, InMemoryTransport } from '@modelcontextprotocol/client';
import { mkdir, mkdtemp, writeFile, readFile, rename, rm, realpath } from 'node:fs/promises';
import { join } from 'node:path';
import { expect, it, vi } from 'vitest';
import { createArtifactBinarySession } from '../../src/composition/binary.js';
import { createServer } from '../../src/server/createServer.js';
import { DirectoryArtifactReader } from '../../src/artifacts/DirectoryArtifactReader.js';
import { ArtifactReaderFailure } from '../../src/artifacts/ArtifactReader.js';
import { parseEvidence } from '../../src/domain/evidence.js';
const root = async () => realpath(await mkdtemp(join(process.env.REPRO_ROOT!, 'case-')));
const connect = async () => {
  const session = await createArtifactBinarySession(process.env);
  const server = createServer({kind:'session',session});
  const client = new Client({name:'artifact-reproduction',version:'1'});
  const [a,b] = InMemoryTransport.createLinkedPair();
  await server.connect(b); await client.connect(a);
  return {client, close: async () => { await client.close();await server.close();await session.close(); }};
};
const error = (r:any) => JSON.parse(r.content.find((x:any)=>x.type==='text').text).error;

it('a replaced Interface Builder document is reported as an invalid archive through MCP', async () => {
 const dir = await root();const app = join(dir,'Fixture.app');const resources=join(app,'Contents','Resources');
 const path=join(resources,'Main.nib');
 await mkdir(resources,{recursive:true});
 await writeFile(join(app,'Contents','Info.plist'),'<plist><dict><key>CFBundleIdentifier</key><string>org.example.fixture</string></dict></plist>');
 await writeFile(path,'<plist><dict><key>com.apple.ibtool.document.objects</key><dict><key>button</key><dict><key>customClass</key><string>NSButton</string><key>label</key><string>Build</string></dict></dict></dict></plist>');
 const mcp=await connect();const original=DirectoryArtifactReader.prototype.open;
 let observed: unknown;let replace=false;
 const spy=vi.spyOn(DirectoryArtifactReader.prototype,'open').mockImplementation(async function(entry,signal){
  if(replace && entry.path.endsWith('Main.nib')) {
   replace=false;await rename(path,path+'.original');await writeFile(path,await readFile(path+'.original'));
  }
  try{return await original.call(this,entry,signal);}catch(cause){observed=cause;throw cause;}
 });
 try {
  expect((await mcp.client.callTool({name:'open_bundle_resources',arguments:{path:app}})).isError).not.toBe(true);
  const invoke=()=>mcp.client.callTool({name:'decode_interface_builder',arguments:{detail:'complete'}});
  const control=await invoke();expect(control.isError).not.toBe(true);
  expect((parseEvidence(control.structuredContent).normalized_result as any).documents).toHaveLength(1);
  replace=true;const response=await invoke();
  expect(observed).toBeInstanceOf(ArtifactReaderFailure);expect(observed).toMatchObject({reason:'integrity'});
  expect(response.isError).not.toBe(true);
  const result:any=parseEvidence(response.structuredContent).normalized_result;
  expect(result.documents).toEqual([]);
  expect(result.graph.coverage).toContainEqual(expect.objectContaining({facet:'archive_decode',status:'partial',reason:'one_or_more_archives_invalid'}));
  expect(result.limitations.join('\n')).toContain('Directory entry changed before open');
  console.log('IB_IDENTITY',JSON.stringify({readerReason:(observed as ArtifactReaderFailure).reason,isError:response.isError??false,documents:result.documents,coverage:result.graph.coverage,limitations:result.limitations}).replaceAll(dir,'<fixture-root>'));
  await rm(path);await rename(path+'.original',path);
  const restored:any=parseEvidence((await invoke()).structuredContent).normalized_result;
  expect(restored.documents).toHaveLength(1);expect(restored.graph.nodes).toEqual((parseEvidence(control.structuredContent).normalized_result as any).graph.nodes);
 } finally {spy.mockRestore();await mcp.close();await rm(dir,{recursive:true,force:true});}
},30000);

Expected behavior

A read or identity-validation failure should preserve its typed failure, with recovery appropriate to unavailable access or changed source. Only bytes actually read and rejected by the decoder should be described as invalid archives. It is sufficient to propagate the typed read failure; this report does not require a new partial-result schema.

The reader explicitly detects entry changes, and artifact translation preserves integrity reasons. Repository boundary rules require preserving identity, meaningful reasons and typed expected failures.

Impact and scope

P2: unread or changed documents are misdiagnosed as malformed content in successful partial Evidence. Automated callers cannot branch on the real failure category. The graph does explicitly mark partial/truncated coverage; no complete-coverage or successfully decoded stale-content claim is made.

The readable CLI control and restored permission control returned one document and the Build control. The MCP identity control recovered its exact graph when the original source was restored. Those are demonstrated workarounds on these self-authored fixtures. Natural incidence, EPERM, mid-stream source changes and other platforms were not measured. No target executed, input bytes were not decoded after failed identity validation, and no security boundary was crossed.

REA version

rea-agents 6.7.0; source revision 52415975942a4b9c53a817915b313ccc404f280e. Built CLI and source MCP tests at this revision.

Runtime and platform

macOS 27.0.1 arm64; Node.js v26.12.0, non-root account. Repository Node pin: 24.18.0. No Hopper, Ghidra, IDA, ibtool or target application execution. Source MCP test: repository-pinned Vitest 5.0.3 and SDK InMemoryTransport.

Target and artifact context

Self-authored macOS-layout resource-only app with a valid XML Info.plist and one ibtool-style XML Main.nib containing an NSButton named Build. Permission test uses mode 000. Identity test replaces the selected name with byte-identical content on a different inode.

Interface

MCP

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Permission CLI: readable exit 0; real readFile EACCES control; denied exit 0; restored exit 0 with original graph. Denied result:

{
  "documents": [],
  "graph": {
    "coverage": [{
      "facet": "archive_decode",
      "status": "partial",
      "reason": "one_or_more_archives_invalid",
      "examined": 1,
      "omitted": 0
    }],
    "truncated": true
  }
}

The limitation includes Main.nib: Could not open entry ... (EACCES).

Identity MCP: the intercepted reader failure is an actual ArtifactReaderFailure with reason integrity and message Directory entry changed before open: Contents/Resources/Main.nib. The response has isError absent/false, no documents and the same partial invalid-archive coverage. Its limitation says Some Interface Builder archives could not be decoded: Contents/Resources/Main.nib: Directory entry changed before open: Contents/Resources/Main.nib.

The final standalone identity test passed one test, including the initial and restored graph controls. It uses no external analysis engine.

Typed outcome or recovery expected

Preserve the typed identity/read outcome rather than consuming it as a decode error. Integrity should remain category integrity_mismatch under the existing artifact translation. A separately needed permission-classification fix must also survive this per-document boundary. Preserve genuine malformed-document partial coverage and decode-budget handling.

Analysis or suspected cause

Source-derived: readEntry is inside the per-document try; it opens and streams the entry. The catch only distinguishes aborted signals and decode-budget exceptions, then adds every other exception to invalid. Coverage and limitations project invalid as a successful partial graph. Keep typed read failures outside the malformed-content catch or explicitly propagate them before recording invalid bytes.

Additional context

Fetched origin/main at d4c637f4cfcb7ae3b48d0c3047f0e9171d43b26d. The relevant producer and classification lines are unchanged. Changes elsewhere in the two shared projection/presentation files concern captured-output inclusion and fixed resource allowance remediation. Later main was source-inspected, not executed. No repaired software or known-good revision is established.

#5912 concerns reservation retention after an actual malformed plist fails decoding; its repair releases representation budget. This failure occurs before decode and requires preserving reader errors, so it remains after a budget-release fix. #5229 / PR #5230 concern directory inventory omissions; this analyzer uses its own per-document catch. #5992 concerns asset-catalog finalization replacing a primary error. #5953, #5970, #5991, #5997, #6004, #5873 and #5949 classify filesystem failures at other producers. Permission classification in the shared directory reader is independently needed; correcting it alone cannot repair this catch, which consumes any non-budget failure. No independent cancellation defect is asserted: an aborted caller signal already causes rethrow.

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6066 ### 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` exits successfully when a selected readable-format nib cannot be opened due to EACCES. It returns no decoded documents, `graph.truncated: true`, and archive coverage reason `one_or_more_archives_invalid`. The read error survives only as a limitation describing an archive that could not be decoded. A separate production MCP test replaces a document with byte-identical new-inode content after selection. The actual reader throws `ArtifactReaderFailure` reason `integrity`, but the tool also returns successful Evidence with the same invalid-archive coverage. Restoring the original input restores the exact control graph. ### Reproduction Two executions isolate permission and identity failures. For the real permission denial, save this executed CLI driver outside a prepared checkout as `ib-permission-reproduction.mjs`, set `REPRO_ROOT` to an existing disposable writable directory outside the checkout, then run it from the checkout using `node ib-permission-reproduction.mjs`. Run as a non-root POSIX user. ```js import { mkdir, mkdtemp, writeFile, chmod, readFile, rm } from 'node:fs/promises'; import { join } from 'node:path'; import { spawnSync } from 'node:child_process'; import assert from 'node:assert/strict'; const root = await mkdtemp(join(process.env.REPRO_ROOT, 'permission-case-')); const app = join(root, 'Fixture.app'); const resources = join(app, 'Contents', 'Resources'); await mkdir(resources, { recursive: true }); await writeFile(join(app, 'Contents', 'Info.plist'), '<plist><dict><key>CFBundleIdentifier</key><string>org.example.fixture</string></dict></plist>'); const env = { ...process.env, REA_LOG_LEVEL: 'silent' }; for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_STATE_HOME', 'TMPDIR']) { env[key] = join(root, key.toLowerCase()); await mkdir(env[key]); } const path = join(resources, 'Main.nib'); await writeFile(path, '<plist><dict><key>com.apple.ibtool.document.objects</key><dict><key>button</key><dict><key>customClass</key><string>NSButton</string><key>label</key><string>Build</string></dict></dict></dict></plist>'); const args = ['scripts/rea.mjs', 'decode-interface-builder', app, '--json']; const run = (label) => { const child = spawnSync(process.execPath, args, { env, encoding: 'utf8', timeout: 45000 }); if (child.error) throw child.error; assert.equal(child.stderr, ''); const output = JSON.parse(child.stdout); const result = output.normalized_result ?? output; console.log(JSON.stringify({ label, exit: child.status, result }).replaceAll(root, '<fixture-root>')); return { exit: child.status, result }; }; try { const control = run('readable'); assert.equal(control.exit, 0); await chmod(path, 0); await assert.rejects(readFile(path), { code: 'EACCES' }); const denied = run('denied'); assert.equal(denied.exit, 0); assert.deepEqual(denied.result.documents, []); assert(denied.result.graph.coverage.some(x => x.facet === 'archive_decode' && x.reason === 'one_or_more_archives_invalid')); assert(denied.result.limitations.some(x => x.includes('EACCES'))); await chmod(path, 0o600); const restored = run('restored'); assert.equal(restored.exit, 0); assert.deepEqual(restored.result.graph.nodes, control.result.graph.nodes); } finally { await chmod(path, 0o600); await rm(root, { recursive: true, force: true }); } ``` For the controlled identity change, save the following executed focused test as `tests/process-global/interfaceBuilderReadFailure.test.ts` and run `node node_modules/vitest/vitest.mjs run tests/process-global/interfaceBuilderReadFailure.test.ts --maxWorkers=1` with `REPRO_ROOT` set as above. The wrapper changes only timing: it replaces the fixture just before the real reader opens the enumerated entry. No filesystem errors, filesystem implementation, parser, provider or projection are simulated. The test characterizes the faulty behavior and therefore passes while it is present. ```ts import { Client, InMemoryTransport } from '@modelcontextprotocol/client'; import { mkdir, mkdtemp, writeFile, readFile, rename, rm, realpath } from 'node:fs/promises'; import { join } from 'node:path'; import { expect, it, vi } from 'vitest'; import { createArtifactBinarySession } from '../../src/composition/binary.js'; import { createServer } from '../../src/server/createServer.js'; import { DirectoryArtifactReader } from '../../src/artifacts/DirectoryArtifactReader.js'; import { ArtifactReaderFailure } from '../../src/artifacts/ArtifactReader.js'; import { parseEvidence } from '../../src/domain/evidence.js'; const root = async () => realpath(await mkdtemp(join(process.env.REPRO_ROOT!, 'case-'))); const connect = async () => { const session = await createArtifactBinarySession(process.env); const server = createServer({kind:'session',session}); const client = new Client({name:'artifact-reproduction',version:'1'}); const [a,b] = InMemoryTransport.createLinkedPair(); await server.connect(b); await client.connect(a); return {client, close: async () => { await client.close();await server.close();await session.close(); }}; }; const error = (r:any) => JSON.parse(r.content.find((x:any)=>x.type==='text').text).error; it('a replaced Interface Builder document is reported as an invalid archive through MCP', async () => { const dir = await root();const app = join(dir,'Fixture.app');const resources=join(app,'Contents','Resources'); const path=join(resources,'Main.nib'); await mkdir(resources,{recursive:true}); await writeFile(join(app,'Contents','Info.plist'),'<plist><dict><key>CFBundleIdentifier</key><string>org.example.fixture</string></dict></plist>'); await writeFile(path,'<plist><dict><key>com.apple.ibtool.document.objects</key><dict><key>button</key><dict><key>customClass</key><string>NSButton</string><key>label</key><string>Build</string></dict></dict></dict></plist>'); const mcp=await connect();const original=DirectoryArtifactReader.prototype.open; let observed: unknown;let replace=false; const spy=vi.spyOn(DirectoryArtifactReader.prototype,'open').mockImplementation(async function(entry,signal){ if(replace && entry.path.endsWith('Main.nib')) { replace=false;await rename(path,path+'.original');await writeFile(path,await readFile(path+'.original')); } try{return await original.call(this,entry,signal);}catch(cause){observed=cause;throw cause;} }); try { expect((await mcp.client.callTool({name:'open_bundle_resources',arguments:{path:app}})).isError).not.toBe(true); const invoke=()=>mcp.client.callTool({name:'decode_interface_builder',arguments:{detail:'complete'}}); const control=await invoke();expect(control.isError).not.toBe(true); expect((parseEvidence(control.structuredContent).normalized_result as any).documents).toHaveLength(1); replace=true;const response=await invoke(); expect(observed).toBeInstanceOf(ArtifactReaderFailure);expect(observed).toMatchObject({reason:'integrity'}); expect(response.isError).not.toBe(true); const result:any=parseEvidence(response.structuredContent).normalized_result; expect(result.documents).toEqual([]); expect(result.graph.coverage).toContainEqual(expect.objectContaining({facet:'archive_decode',status:'partial',reason:'one_or_more_archives_invalid'})); expect(result.limitations.join('\n')).toContain('Directory entry changed before open'); console.log('IB_IDENTITY',JSON.stringify({readerReason:(observed as ArtifactReaderFailure).reason,isError:response.isError??false,documents:result.documents,coverage:result.graph.coverage,limitations:result.limitations}).replaceAll(dir,'<fixture-root>')); await rm(path);await rename(path+'.original',path); const restored:any=parseEvidence((await invoke()).structuredContent).normalized_result; expect(restored.documents).toHaveLength(1);expect(restored.graph.nodes).toEqual((parseEvidence(control.structuredContent).normalized_result as any).graph.nodes); } finally {spy.mockRestore();await mcp.close();await rm(dir,{recursive:true,force:true});} },30000); ``` ### Expected behavior A read or identity-validation failure should preserve its typed failure, with recovery appropriate to unavailable access or changed source. Only bytes actually read and rejected by the decoder should be described as invalid archives. It is sufficient to propagate the typed read failure; this report does not require a new partial-result schema. [The reader explicitly detects entry changes](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/DirectoryArtifactReader.ts#L282-L294), and [artifact translation preserves integrity reasons](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/ArtifactOperationFailure.ts#L20-L39). [Repository boundary rules](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/AGENTS.md#L19-L31) require preserving identity, meaningful reasons and typed expected failures. ### Impact and scope P2: unread or changed documents are misdiagnosed as malformed content in successful partial Evidence. Automated callers cannot branch on the real failure category. The graph does explicitly mark partial/truncated coverage; no complete-coverage or successfully decoded stale-content claim is made. The readable CLI control and restored permission control returned one document and the Build control. The MCP identity control recovered its exact graph when the original source was restored. Those are demonstrated workarounds on these self-authored fixtures. Natural incidence, EPERM, mid-stream source changes and other platforms were not measured. No target executed, input bytes were not decoded after failed identity validation, and no security boundary was crossed. ### REA version `rea-agents` 6.7.0; source revision `52415975942a4b9c53a817915b313ccc404f280e`. Built CLI and source MCP tests at this revision. ### Runtime and platform macOS 27.0.1 arm64; Node.js v26.12.0, non-root account. Repository Node pin: 24.18.0. No Hopper, Ghidra, IDA, ibtool or target application execution. Source MCP test: repository-pinned Vitest 5.0.3 and SDK InMemoryTransport. ### Target and artifact context Self-authored macOS-layout resource-only app with a valid XML Info.plist and one ibtool-style XML `Main.nib` containing an NSButton named Build. Permission test uses mode 000. Identity test replaces the selected name with byte-identical content on a different inode. ### Interface MCP ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Permission CLI: readable exit 0; real readFile EACCES control; denied exit 0; restored exit 0 with original graph. Denied result: ```json { "documents": [], "graph": { "coverage": [{ "facet": "archive_decode", "status": "partial", "reason": "one_or_more_archives_invalid", "examined": 1, "omitted": 0 }], "truncated": true } } ``` The limitation includes `Main.nib: Could not open entry ... (EACCES)`. Identity MCP: the intercepted reader failure is an actual `ArtifactReaderFailure` with reason `integrity` and message `Directory entry changed before open: Contents/Resources/Main.nib`. The response has `isError` absent/false, no documents and the same partial invalid-archive coverage. Its limitation says `Some Interface Builder archives could not be decoded: Contents/Resources/Main.nib: Directory entry changed before open: Contents/Resources/Main.nib`. The final standalone identity test passed one test, including the initial and restored graph controls. It uses no external analysis engine. ### Typed outcome or recovery expected Preserve the typed identity/read outcome rather than consuming it as a decode error. Integrity should remain category `integrity_mismatch` under the existing artifact translation. A separately needed permission-classification fix must also survive this per-document boundary. Preserve genuine malformed-document partial coverage and decode-budget handling. ### Analysis or suspected cause Source-derived: [readEntry is inside the per-document try](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L99-L120); [it opens and streams the entry](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L735-L763). [The catch only distinguishes aborted signals and decode-budget exceptions](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L210-L223), then adds every other exception to invalid. [Coverage and limitations project invalid as a successful partial graph](https://github.com/morluto/rea/blob/52415975942a4b9c53a817915b313ccc404f280e/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L333-L410). Keep typed read failures outside the malformed-content catch or explicitly propagate them before recording invalid bytes. ### Additional context Fetched `origin/main` at `d4c637f4cfcb7ae3b48d0c3047f0e9171d43b26d`. The relevant producer and classification lines are unchanged. Changes elsewhere in the two shared projection/presentation files concern captured-output inclusion and fixed resource allowance remediation. Later main was source-inspected, not executed. No repaired software or known-good revision is established. #5912 concerns reservation retention after an actual malformed plist fails decoding; its repair releases representation budget. This failure occurs before decode and requires preserving reader errors, so it remains after a budget-release fix. #5229 / PR #5230 concern directory inventory omissions; this analyzer uses its own per-document catch. #5992 concerns asset-catalog finalization replacing a primary error. #5953, #5970, #5991, #5997, #6004, #5873 and #5949 classify filesystem failures at other producers. Permission classification in the shared directory reader is independently needed; correcting it alone cannot repair this catch, which consumes any non-budget failure. No independent cancellation defect is asserted: an aborted caller signal already causes rethrow.
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#3706
No description provided.