From ef1a0cc65af7918ef7204a39f42a4299b486c453 Mon Sep 17 00:00:00 2001 From: ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Date: Wed, 7 Oct 2026 21:09:33 +0800 Subject: [PATCH] refactor(apple): group artifact producers and verification (#952) * refactor(apple): group artifact producers and verification * test(apple): run affected native plist CLI regressions --- .github/workflows/ci.yml | 2 +- docs/capability-migration.md | 29 +++++++++++++++++++ docs/testing.md | 6 ++++ package.json | 10 +++---- .../apple/macos-bundle.mjs} | 0 scripts/lib/module-boundaries.mjs | 1 + .../apple/asset-catalog.mjs} | 9 ++++-- .../apple/dispatch.mjs} | 6 ++-- .../apple/interface-builder.mjs} | 6 ++-- .../apple/keyed-archive.mjs} | 8 ++--- .../apple/macos-bundle.mjs} | 4 +-- src/application/NativeUiActionTrace.ts | 2 +- .../{ => apple}/AppleApplicationService.ts | 12 ++++---- src/artifacts/ArtifactProvider.ts | 8 ++--- .../apple}/AppleAssetCatalogAnalysis.test.ts | 0 .../apple}/AppleAssetCatalogAnalysis.ts | 12 ++++---- .../apple}/InterfaceBuilderAnalysis.ts | 17 +++++------ .../{ => apple}/KeyedArchiveReader.test.ts | 0 .../{ => apple}/KeyedArchiveReader.ts | 12 ++++---- .../{ => apple}/NibArchive.fixture.ts | 0 src/artifacts/{ => apple}/NibArchive.test.ts | 0 src/artifacts/{ => apple}/NibArchive.ts | 2 +- .../apple}/NibViewHierarchy.test.ts | 0 .../apple}/NibViewHierarchy.ts | 4 +-- src/cli/applicationCommands.ts | 4 +-- src/contracts/applicationToolContracts.ts | 2 +- src/contracts/artifactToolContracts.ts | 4 +-- src/contracts/toolOutputSchemaGroups.ts | 6 ++-- .../{ => apple}/appleApplication.test.ts | 6 ++-- src/domain/{ => apple}/appleApplication.ts | 8 ++--- .../{ => apple}/appleAssetCatalog.test.ts | 0 src/domain/{ => apple}/appleAssetCatalog.ts | 4 +-- src/domain/{ => apple}/appleBundleAnatomy.ts | 2 +- .../{ => apple}/interfaceBuilderGraph.test.ts | 0 .../{ => apple}/interfaceBuilderGraph.ts | 2 +- .../interfaceBuilderKeyedArchive.ts | 2 +- src/domain/{ => apple}/keyedArchive.ts | 2 +- src/domain/{ => apple}/plistValue.test.ts | 0 src/domain/{ => apple}/plistValue.ts | 2 +- src/domain/nativeInvestigationGraph.test.ts | 2 +- src/native/parsers/plist.ts | 2 +- .../projectMobileApplicationGraph.ts | 2 +- .../filesystem/interfaceBuilderBundle.test.ts | 4 +-- .../filesystem/nativeArtifactGoldens.test.ts | 4 +-- .../filesystem/nibNativeHierarchy.test.ts | 4 +-- .../mcp/artifactMcp.inlineInventory.test.ts | 2 +- .../native/keyedArchiveEncoding.test.ts | 2 +- .../appleApplication.test.ts | 4 +-- tests/evaluation/moduleBoundaries.test.ts | 19 ++++++++++++ turbo.json | 2 ++ 50 files changed, 149 insertions(+), 92 deletions(-) rename scripts/{lib/macos-bundle-fixture.mjs => fixtures/apple/macos-bundle.mjs} (100%) rename scripts/{verify-asset-catalog.mjs => verify/apple/asset-catalog.mjs} (93%) rename scripts/{verify-apple-dispatch.mjs => verify/apple/dispatch.mjs} (96%) rename scripts/{verify-interface-builder.mjs => verify/apple/interface-builder.mjs} (93%) rename scripts/{verify-keyed-archive.mjs => verify/apple/keyed-archive.mjs} (94%) rename scripts/{verify-macos-bundle.mjs => verify/apple/macos-bundle.mjs} (98%) rename src/application/{ => apple}/AppleApplicationService.ts (66%) rename src/{application => artifacts/apple}/AppleAssetCatalogAnalysis.test.ts (100%) rename src/{application => artifacts/apple}/AppleAssetCatalogAnalysis.ts (95%) rename src/{application => artifacts/apple}/InterfaceBuilderAnalysis.ts (96%) rename src/artifacts/{ => apple}/KeyedArchiveReader.test.ts (100%) rename src/artifacts/{ => apple}/KeyedArchiveReader.ts (92%) rename src/artifacts/{ => apple}/NibArchive.fixture.ts (100%) rename src/artifacts/{ => apple}/NibArchive.test.ts (100%) rename src/artifacts/{ => apple}/NibArchive.ts (99%) rename src/{application => artifacts/apple}/NibViewHierarchy.test.ts (100%) rename src/{application => artifacts/apple}/NibViewHierarchy.ts (97%) rename src/domain/{ => apple}/appleApplication.test.ts (98%) rename src/domain/{ => apple}/appleApplication.ts (98%) rename src/domain/{ => apple}/appleAssetCatalog.test.ts (100%) rename src/domain/{ => apple}/appleAssetCatalog.ts (98%) rename src/domain/{ => apple}/appleBundleAnatomy.ts (99%) rename src/domain/{ => apple}/interfaceBuilderGraph.test.ts (100%) rename src/domain/{ => apple}/interfaceBuilderGraph.ts (99%) rename src/domain/{ => apple}/interfaceBuilderKeyedArchive.ts (99%) rename src/domain/{ => apple}/keyedArchive.ts (99%) rename src/domain/{ => apple}/plistValue.test.ts (100%) rename src/domain/{ => apple}/plistValue.ts (97%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f851393e9..d1bb5bef54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -311,7 +311,7 @@ jobs: - name: Real binary metadata and Interface Builder integration run: npm run verify:apple-dispatch && npm run verify:interface-builder - name: Native plist CLI selection regressions - run: npm run test:focused -- tests/boundary/cli/nativePlistCli.test.ts + run: npm run test:focused -- tests/boundary/cli/nativePlistCli.test.ts tests/boundary/cli/nativePlistPrototypeKeyCli.test.ts tests/boundary/cli/nativePlistSelectionFailureCli.test.ts reconstruction-readiness: name: Reconstruction readiness diff --git a/docs/capability-migration.md b/docs/capability-migration.md index 5761279c1c..3789591d62 100644 --- a/docs/capability-migration.md +++ b/docs/capability-migration.md @@ -356,3 +356,32 @@ repository-root default. Both point to `_reference/firmware-integration/generate when invoked through the documented npm commands. Optional ext4/Ghidra lanes keep their own prerequisites. Source-fixture generation and synthetic producer tests do not establish real Binwalk/Unblob analysis or another host's execution support. + +## Apple artifact capability ownership + +`src/domain/apple/` owns Apple application anatomy/projection, asset catalog +facts, Interface Builder graphs, keyed archive semantics and plist values. +`src/application/apple/AppleApplicationService.ts` retains the shared workflow +that projects authenticated IPA/macOS inventory Evidence. + +`src/artifacts/apple/` owns the actual producer boundary: directory acquisition, +assetutil invocation, plist/NIB decoding, encoded view-parent interpretation and +keyed archive inspection. These helpers are used by ArtifactProvider, retain +its existing typed analysis boundary, injected assetutil seam and original reader +cleanup, and do not require a new port for each helper. Producer code no longer +lives in the application layer. Guards reject application/composition/caller +imports from this owner while admitting pure facts and shared artifact readers. +Adapter-source tests retain their assertions in the existing forked adapter lane. + +`scripts/verify/apple/` groups archive, asset catalog, Interface Builder, +Objective-C/Swift dispatch and macOS bundle verification. The macOS bundle fixture +builder lives in `scripts/fixtures/apple/`; NIB byte fixtures stay beside their +artifact decoder. Existing format-specific conformance sources and goldens keep +their locations, and relocated verifiers resolve them against their own file +URLs. Public npm entrypoints and CLI/MCP contracts stay stable; generated-document +cache inputs include the relocated runtime scripts and fixture builder. + +Portable decoder and injected producer tests establish their format/boundary +claims. Actual Swift/Xcode, assetutil, native NIB, bundle signing and DMG lifecycle +claims require the real Apple lane. Native binary API/value-flow semantics and +shared cross-domain contract aggregates keep their separate owners. diff --git a/docs/testing.md b/docs/testing.md index e76e09f107..e7f406c9fd 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -89,6 +89,12 @@ then checks that `inspect-artifact` plus `project-apple-application-graph` report the same bundle anatomy for all three through the CLI, with stdio MCP parity. It also checks that the DMG is detached afterwards. It runs in macOS CI. +Apple artifact verifiers live in `scripts/verify/apple/`, with the macOS bundle +builder under `scripts/fixtures/apple/` and NIB byte fixtures beside the decoder +in `src/artifacts/apple/`. The npm entrypoints are unchanged. Format-specific +Swift/XIB/asset sources and goldens retain their locations; real Apple workflows +resolve them from the verifier file URL and run in the macOS CI lane. + MCP SDK transport tests with recording providers remain integration tests. They are useful for schema drift and failure projection but do not prove that Hopper, Ghidra or another substituted engine works. `verify:package` proves diff --git a/package.json b/package.json index ad1e9cab92..bfdb50a050 100644 --- a/package.json +++ b/package.json @@ -121,17 +121,17 @@ "typecheck": "tsc --noEmit", "verify:test-temp-hygiene": "npm run build:cached && node scripts/verify-test-temp-hygiene.mjs", "verify:hopper": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper.mjs", - "verify:apple-dispatch": "npm run build:cached && node scripts/verify-apple-dispatch.mjs", + "verify:apple-dispatch": "npm run build:cached && node scripts/verify/apple/dispatch.mjs", "verify:native-ui": "npm run build:cached && node scripts/verify-native-ui.mjs", - "verify:keyed-archive": "npm run build:cached && node scripts/verify-keyed-archive.mjs", - "verify:macos-bundle": "npm run build:cached && node scripts/verify-macos-bundle.mjs", + "verify:keyed-archive": "npm run build:cached && node scripts/verify/apple/keyed-archive.mjs", + "verify:macos-bundle": "npm run build:cached && node scripts/verify/apple/macos-bundle.mjs", "verify:ghidra": "npm run build:cached && node scripts/verify-real-ghidra.mjs", "verify:ida": "npm run build:cached && node scripts/verify-real-ida.mjs", "verify:ghidra:switch": "npm run build:cached && node scripts/verify-real-ghidra-switch.mjs", "verify:ghidra:dos": "npm run build:cached && node scripts/verify-real-ghidra-dos.mjs", "verify:ghidra:com": "npm run build:cached && node scripts/verify-real-ghidra-com.mjs", "verify:ghidra:aarch64-jump-table": "npm run build:cached && node scripts/verify-real-ghidra.mjs --aarch64-jump-table", - "verify:interface-builder": "npm run build:cached && node scripts/verify-interface-builder.mjs", + "verify:interface-builder": "npm run build:cached && node scripts/verify/apple/interface-builder.mjs", "verify:ghidra:cross-format": "npm run build:cached && node scripts/verify-real-ghidra.mjs --cross-format", "verify:ghidra:windows": "npm run build:cached && npm run build:ghidra-windows-fixture && node scripts/verify-real-ghidra-windows.mjs", "verify:browser": "npm run build:cached && node scripts/verify-real-browser.mjs", @@ -171,7 +171,7 @@ "docs:error-schema": "npm run build:cached && node scripts/generate-error-schema.mjs", "prepack": "node scripts/prepack.mjs", "prepare": "node scripts/prepare.mjs", - "verify:asset-catalog": "npm run build:cached && node scripts/verify-asset-catalog.mjs", + "verify:asset-catalog": "npm run build:cached && node scripts/verify/apple/asset-catalog.mjs", "verify:native-ui:permissions": "npm run build:cached && node scripts/verify-native-ui.mjs --allow-permission-denial", "test:focused": "node scripts/run-development-tests.mjs focused", "build:windows-native": "node scripts/build-windows-native.mjs", diff --git a/scripts/lib/macos-bundle-fixture.mjs b/scripts/fixtures/apple/macos-bundle.mjs similarity index 100% rename from scripts/lib/macos-bundle-fixture.mjs rename to scripts/fixtures/apple/macos-bundle.mjs diff --git a/scripts/lib/module-boundaries.mjs b/scripts/lib/module-boundaries.mjs index e43ccd44cc..ca1e4d933d 100644 --- a/scripts/lib/module-boundaries.mjs +++ b/scripts/lib/module-boundaries.mjs @@ -69,6 +69,7 @@ const failedBoundary = (file, target) => { return "provider-construction"; if ( (file.startsWith("src/artifacts/javascript/") || + file.startsWith("src/artifacts/apple/") || /^src\/artifacts\/ArtifactHash\.(?:js|ts)$/u.test(file)) && (["application", "composition", "server", "cli", "main"].includes( targetLayer, diff --git a/scripts/verify-asset-catalog.mjs b/scripts/verify/apple/asset-catalog.mjs similarity index 93% rename from scripts/verify-asset-catalog.mjs rename to scripts/verify/apple/asset-catalog.mjs index 84087f3710..8a62396f14 100644 --- a/scripts/verify-asset-catalog.mjs +++ b/scripts/verify/apple/asset-catalog.mjs @@ -10,7 +10,7 @@ import { artifactCli, artifactMcpResult, withArtifactMcp, -} from "./lib/artifact-e2e.mjs"; +} from "../../lib/artifact-e2e.mjs"; if (process.platform !== "darwin") throw new Error( @@ -30,7 +30,7 @@ try { "clang", fileURLToPath( new URL( - "../tests/conformance/interface-builder/fixture.c", + "../../../tests/conformance/interface-builder/fixture.c", import.meta.url, ), ), @@ -44,7 +44,10 @@ try { await exec("/usr/bin/xcrun", [ "actool", fileURLToPath( - new URL("../tests/conformance/native/Assets.xcassets", import.meta.url), + new URL( + "../../../tests/conformance/native/Assets.xcassets", + import.meta.url, + ), ), "--compile", resources, diff --git a/scripts/verify-apple-dispatch.mjs b/scripts/verify/apple/dispatch.mjs similarity index 96% rename from scripts/verify-apple-dispatch.mjs rename to scripts/verify/apple/dispatch.mjs index 25e80c2799..3e108c10ed 100644 --- a/scripts/verify-apple-dispatch.mjs +++ b/scripts/verify/apple/dispatch.mjs @@ -4,8 +4,8 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; -import { parseBinaryTarget } from "../dist/application/BinaryTargetResolver.js"; -import { inspectAppleDispatchMetadata } from "../dist/native/AppleDispatchMetadata.js"; +import { parseBinaryTarget } from "../../../dist/application/BinaryTargetResolver.js"; +import { inspectAppleDispatchMetadata } from "../../../dist/native/AppleDispatchMetadata.js"; if (process.platform !== "darwin") throw new Error( @@ -14,7 +14,7 @@ if (process.platform !== "darwin") const exec = promisify(execFile); const source = (name) => fileURLToPath( - new URL(`../tests/conformance/native/${name}`, import.meta.url), + new URL(`../../../tests/conformance/native/${name}`, import.meta.url), ); /** Both link modes: legacy LC_DYLD_INFO binds and the default chained fixups. */ diff --git a/scripts/verify-interface-builder.mjs b/scripts/verify/apple/interface-builder.mjs similarity index 93% rename from scripts/verify-interface-builder.mjs rename to scripts/verify/apple/interface-builder.mjs index 350411dd0b..1f8ec323e0 100644 --- a/scripts/verify-interface-builder.mjs +++ b/scripts/verify/apple/interface-builder.mjs @@ -8,8 +8,8 @@ import { join } from "node:path"; import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; -import { parseBinaryTarget } from "../dist/application/BinaryTargetResolver.js"; -import { ArtifactProvider } from "../dist/artifacts/ArtifactProvider.js"; +import { parseBinaryTarget } from "../../../dist/application/BinaryTargetResolver.js"; +import { ArtifactProvider } from "../../../dist/artifacts/ArtifactProvider.js"; const exec = promisify(execFile); const fixtureRoot = await mkdtemp(join(tmpdir(), "rea-interface-builder-")); @@ -18,7 +18,7 @@ const resourcesPath = join(appPath, "Contents", "Resources"); const executablePath = join(appPath, "Contents", "MacOS", "Fixture"); const nibPath = join(resourcesPath, "Main.nib"); const sourceRoot = fileURLToPath( - new URL("../tests/conformance/interface-builder/", import.meta.url), + new URL("../../../tests/conformance/interface-builder/", import.meta.url), ); try { diff --git a/scripts/verify-keyed-archive.mjs b/scripts/verify/apple/keyed-archive.mjs similarity index 94% rename from scripts/verify-keyed-archive.mjs rename to scripts/verify/apple/keyed-archive.mjs index b9f9aa4802..924c3bb0e1 100644 --- a/scripts/verify-keyed-archive.mjs +++ b/scripts/verify/apple/keyed-archive.mjs @@ -10,7 +10,7 @@ import { artifactCli, artifactMcpResult, withArtifactMcp, -} from "./lib/artifact-e2e.mjs"; +} from "../../lib/artifact-e2e.mjs"; if (process.platform !== "darwin") throw new Error( @@ -25,7 +25,7 @@ try { join(root, "modules"), fileURLToPath( new URL( - "../tests/conformance/native/keyed-archive.swift", + "../../../tests/conformance/native/keyed-archive.swift", import.meta.url, ), ), @@ -66,7 +66,7 @@ try { const expected = JSON.parse( await readFile( new URL( - "../tests/fixtures/golden/keyed-archive/graph.json", + "../../../tests/fixtures/golden/keyed-archive/graph.json", import.meta.url, ), "utf8", @@ -124,7 +124,7 @@ try { join(root, "modules"), fileURLToPath( new URL( - "../tests/conformance/native/keyed-archive-uid-root.swift", + "../../../tests/conformance/native/keyed-archive-uid-root.swift", import.meta.url, ), ), diff --git a/scripts/verify-macos-bundle.mjs b/scripts/verify/apple/macos-bundle.mjs similarity index 98% rename from scripts/verify-macos-bundle.mjs rename to scripts/verify/apple/macos-bundle.mjs index 58fbffd27a..bc4522b731 100644 --- a/scripts/verify-macos-bundle.mjs +++ b/scripts/verify/apple/macos-bundle.mjs @@ -9,11 +9,11 @@ import { artifactCliEvidence, artifactMcpResult, withArtifactMcp, -} from "./lib/artifact-e2e.mjs"; +} from "../../lib/artifact-e2e.mjs"; import { buildMacosBundleFixture, preflightMacosBundleFixture, -} from "./lib/macos-bundle-fixture.mjs"; +} from "../../fixtures/apple/macos-bundle.mjs"; const exec = promisify(execFile); diff --git a/src/application/NativeUiActionTrace.ts b/src/application/NativeUiActionTrace.ts index f94051a121..25e9b9dc37 100644 --- a/src/application/NativeUiActionTrace.ts +++ b/src/application/NativeUiActionTrace.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import type { AnalysisOperationPort } from "./AnalysisProvider.js"; import type { EnhancedResult } from "./EnhancedToolTypes.js"; import type { enhancedInputSchemas } from "../contracts/enhancedInputs.js"; -import { interfaceBuilderAnalysisSchema } from "../domain/interfaceBuilderGraph.js"; +import { interfaceBuilderAnalysisSchema } from "../domain/apple/interfaceBuilderGraph.js"; import { nativeInvestigationGraphSchema, nativeInvestigationTraceSchema, diff --git a/src/application/AppleApplicationService.ts b/src/application/apple/AppleApplicationService.ts similarity index 66% rename from src/application/AppleApplicationService.ts rename to src/application/apple/AppleApplicationService.ts index 75c24540c0..a30cb654c0 100644 --- a/src/application/AppleApplicationService.ts +++ b/src/application/apple/AppleApplicationService.ts @@ -1,12 +1,12 @@ -import type { AnalysisError } from "../domain/analysisErrorBase.js"; -import type { Evidence } from "../domain/evidence.js"; +import type { AnalysisError } from "../../domain/analysisErrorBase.js"; +import type { Evidence } from "../../domain/evidence.js"; import { appleApplicationProjectionInputSchema, projectAppleApplication, -} from "../domain/appleApplication.js"; -import type { Result } from "../domain/result.js"; -import { APPLE_APPLICATION_PROVIDER } from "./InvestigationProviders.js"; -import { projectInventoryEvidence } from "./InventoryProjectionEvidence.js"; +} from "../../domain/apple/appleApplication.js"; +import type { Result } from "../../domain/result.js"; +import { APPLE_APPLICATION_PROVIDER } from "../InvestigationProviders.js"; +import { projectInventoryEvidence } from "../InventoryProjectionEvidence.js"; const OPERATION = "project_apple_application_graph" as const; diff --git a/src/artifacts/ArtifactProvider.ts b/src/artifacts/ArtifactProvider.ts index bc0dced1bc..54d9d38269 100644 --- a/src/artifacts/ArtifactProvider.ts +++ b/src/artifacts/ArtifactProvider.ts @@ -7,12 +7,12 @@ import { type ProviderIdentity, type ExecutionOptions, } from "../application/AnalysisProvider.js"; -import { inspectBundleKeyedArchive } from "./KeyedArchiveReader.js"; +import { inspectBundleKeyedArchive } from "./apple/KeyedArchiveReader.js"; import { basename, dirname } from "node:path"; import { inventoryArtifact } from "../application/ArtifactInventory.js"; import { extractArtifact } from "../application/ArtifactExtraction.js"; -import { analyzeInterfaceBuilderBundle } from "../application/InterfaceBuilderAnalysis.js"; -import { analyzeAppleAssetCatalogs } from "../application/AppleAssetCatalogAnalysis.js"; +import { analyzeInterfaceBuilderBundle } from "./apple/InterfaceBuilderAnalysis.js"; +import { analyzeAppleAssetCatalogs } from "./apple/AppleAssetCatalogAnalysis.js"; import { ARTIFACT_ANALYSIS_OPERATIONS, artifactInventoryInputSchema, @@ -24,7 +24,7 @@ import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore. import { ArtifactOperationError } from "../domain/artifactOperationError.js"; import { type AnalysisError } from "../domain/analysisErrorBase.js"; import type { JsonValue } from "../domain/jsonValue.js"; -import { interfaceBuilderLimitsSchema } from "../domain/interfaceBuilderGraph.js"; +import { interfaceBuilderLimitsSchema } from "../domain/apple/interfaceBuilderGraph.js"; import { err, ok } from "../domain/result.js"; import { ArtifactReaderFailure } from "./ArtifactReader.js"; import { diff --git a/src/application/AppleAssetCatalogAnalysis.test.ts b/src/artifacts/apple/AppleAssetCatalogAnalysis.test.ts similarity index 100% rename from src/application/AppleAssetCatalogAnalysis.test.ts rename to src/artifacts/apple/AppleAssetCatalogAnalysis.test.ts diff --git a/src/application/AppleAssetCatalogAnalysis.ts b/src/artifacts/apple/AppleAssetCatalogAnalysis.ts similarity index 95% rename from src/application/AppleAssetCatalogAnalysis.ts rename to src/artifacts/apple/AppleAssetCatalogAnalysis.ts index 8ba8b04c6a..36b88eb134 100644 --- a/src/application/AppleAssetCatalogAnalysis.ts +++ b/src/artifacts/apple/AppleAssetCatalogAnalysis.ts @@ -1,14 +1,14 @@ import { createHash } from "node:crypto"; import { lstat } from "node:fs/promises"; -import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js"; -import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js"; +import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js"; +import { ArtifactReaderFailure } from "../ArtifactReader.js"; import { analyzeInterfaceBuilderBundle } from "./InterfaceBuilderAnalysis.js"; import { appleAssetCatalogInputSchema, parseAppleAssetCatalogRecords, projectAppleAssetCatalogPage, -} from "../domain/appleAssetCatalog.js"; -import { execFileOutput } from "../process/ExecFileOutput.js"; +} from "../../domain/apple/appleAssetCatalog.js"; +import { execFileOutput } from "../../process/ExecFileOutput.js"; const ASSETUTIL = "/usr/bin/assetutil"; const MAX_CATALOG_BYTES = 64 * 1024 * 1024; @@ -105,7 +105,7 @@ export const analyzeAppleAssetCatalogs = async (input: { const inspectAssetCatalogEntry = async (input: { readonly reader: DirectoryArtifactReader; - readonly entry: import("../artifacts/ArtifactReader.js").ArtifactEntry; + readonly entry: import("../ArtifactReader.js").ArtifactEntry; readonly runAssetUtil: ( path: string, signal?: AbortSignal, @@ -237,7 +237,7 @@ const runAssetUtil = async ( const digestBounded = async ( reader: DirectoryArtifactReader, - entry: import("../artifacts/ArtifactReader.js").ArtifactEntry, + entry: import("../ArtifactReader.js").ArtifactEntry, signal?: AbortSignal, ): Promise => { if (entry.declaredSize === null || entry.declaredSize > MAX_CATALOG_BYTES) diff --git a/src/application/InterfaceBuilderAnalysis.ts b/src/artifacts/apple/InterfaceBuilderAnalysis.ts similarity index 96% rename from src/application/InterfaceBuilderAnalysis.ts rename to src/artifacts/apple/InterfaceBuilderAnalysis.ts index 3dc03463f1..6966bbe9c7 100644 --- a/src/application/InterfaceBuilderAnalysis.ts +++ b/src/artifacts/apple/InterfaceBuilderAnalysis.ts @@ -1,28 +1,25 @@ import { createHash } from "node:crypto"; import { parseBinary } from "plist"; -import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js"; -import { projectPlistValue } from "../domain/plistValue.js"; +import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js"; +import { projectPlistValue } from "../../domain/apple/plistValue.js"; import { omittedPrototypeKeysLimitation, parseXmlPropertyList, -} from "../domain/propertyListKeys.js"; -import { - decodeNibArchive, - type NibArchiveDocument, -} from "../artifacts/NibArchive.js"; -import type { ArtifactEntry } from "../artifacts/ArtifactReader.js"; +} from "../../domain/propertyListKeys.js"; +import { decodeNibArchive, type NibArchiveDocument } from "./NibArchive.js"; +import type { ArtifactEntry } from "../ArtifactReader.js"; import { buildInterfaceBuilderAnalysis, interfaceBuilderLimitsSchema, type InterfaceBuilderDocumentInput, -} from "../domain/interfaceBuilderGraph.js"; +} from "../../domain/apple/interfaceBuilderGraph.js"; import { mergeNibHierarchies, projectNibViewHierarchy, type NibHierarchyNode, } from "./NibViewHierarchy.js"; -import { jsonValueSchema, type JsonValue } from "../domain/jsonValue.js"; +import { jsonValueSchema, type JsonValue } from "../../domain/jsonValue.js"; const MAX_DOCUMENT_BYTES = 64 * 1024 * 1024; diff --git a/src/artifacts/KeyedArchiveReader.test.ts b/src/artifacts/apple/KeyedArchiveReader.test.ts similarity index 100% rename from src/artifacts/KeyedArchiveReader.test.ts rename to src/artifacts/apple/KeyedArchiveReader.test.ts diff --git a/src/artifacts/KeyedArchiveReader.ts b/src/artifacts/apple/KeyedArchiveReader.ts similarity index 92% rename from src/artifacts/KeyedArchiveReader.ts rename to src/artifacts/apple/KeyedArchiveReader.ts index b96253d5d8..e948619971 100644 --- a/src/artifacts/KeyedArchiveReader.ts +++ b/src/artifacts/apple/KeyedArchiveReader.ts @@ -2,19 +2,19 @@ import { createHash } from "node:crypto"; import { TextDecoder } from "node:util"; import { parseBinary } from "plist"; import { z } from "zod"; -import type { JsonValue } from "../domain/jsonValue.js"; -import { projectPlistValue } from "../domain/plistValue.js"; +import type { JsonValue } from "../../domain/jsonValue.js"; +import { projectPlistValue } from "../../domain/apple/plistValue.js"; import { omittedPrototypeKeysLimitation, parseXmlPropertyList, -} from "../domain/propertyListKeys.js"; +} from "../../domain/propertyListKeys.js"; import { keyedArchiveInputSchema, keyedArchiveResultSchema, projectKeyedArchive, -} from "../domain/keyedArchive.js"; -import { DirectoryArtifactReader } from "./DirectoryArtifactReader.js"; -import { ArtifactReaderFailure } from "./ArtifactReader.js"; +} from "../../domain/apple/keyedArchive.js"; +import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js"; +import { ArtifactReaderFailure } from "../ArtifactReader.js"; const MAX_BYTES = 64 * 1024 * 1024; diff --git a/src/artifacts/NibArchive.fixture.ts b/src/artifacts/apple/NibArchive.fixture.ts similarity index 100% rename from src/artifacts/NibArchive.fixture.ts rename to src/artifacts/apple/NibArchive.fixture.ts diff --git a/src/artifacts/NibArchive.test.ts b/src/artifacts/apple/NibArchive.test.ts similarity index 100% rename from src/artifacts/NibArchive.test.ts rename to src/artifacts/apple/NibArchive.test.ts diff --git a/src/artifacts/NibArchive.ts b/src/artifacts/apple/NibArchive.ts similarity index 99% rename from src/artifacts/NibArchive.ts rename to src/artifacts/apple/NibArchive.ts index 23d991bed1..c383922d12 100644 --- a/src/artifacts/NibArchive.ts +++ b/src/artifacts/apple/NibArchive.ts @@ -1,4 +1,4 @@ -import type { JsonValue } from "../domain/jsonValue.js"; +import type { JsonValue } from "../../domain/jsonValue.js"; import { TextDecoder } from "node:util"; const MAGIC = Buffer.from("NIBArchive", "ascii"); diff --git a/src/application/NibViewHierarchy.test.ts b/src/artifacts/apple/NibViewHierarchy.test.ts similarity index 100% rename from src/application/NibViewHierarchy.test.ts rename to src/artifacts/apple/NibViewHierarchy.test.ts diff --git a/src/application/NibViewHierarchy.ts b/src/artifacts/apple/NibViewHierarchy.ts similarity index 97% rename from src/application/NibViewHierarchy.ts rename to src/artifacts/apple/NibViewHierarchy.ts index 231f456b6e..61c669e53c 100644 --- a/src/application/NibViewHierarchy.ts +++ b/src/artifacts/apple/NibViewHierarchy.ts @@ -1,5 +1,5 @@ -import type { NibArchiveDocument } from "../artifacts/NibArchive.js"; -import type { JsonValue } from "../domain/jsonValue.js"; +import type { NibArchiveDocument } from "./NibArchive.js"; +import type { JsonValue } from "../../domain/jsonValue.js"; export type NibHierarchyNode = { objectID: string; diff --git a/src/cli/applicationCommands.ts b/src/cli/applicationCommands.ts index 967ecbf6cb..f4a6fb33b0 100644 --- a/src/cli/applicationCommands.ts +++ b/src/cli/applicationCommands.ts @@ -2,7 +2,7 @@ import { reconstructionCoverageEvaluationInputSchema } from "../domain/reconstru import { Cli, z } from "incur"; import { projectAndroidApplicationEvidence } from "../application/android/AndroidApplicationService.js"; -import { projectAppleApplicationEvidence } from "../application/AppleApplicationService.js"; +import { projectAppleApplicationEvidence } from "../application/apple/AppleApplicationService.js"; import { compareApplicationVersionsEvidenceValidated, compareJavaScriptExportShapesEvidenceValidated, @@ -19,7 +19,7 @@ import { AnalysisInputError } from "../domain/analysisErrorCore.js"; import { projectAnalysisError } from "../domain/analysisErrorProjection.js"; import { type AnalysisError } from "../domain/analysisErrorBase.js"; import { androidApplicationProjectionInputSchema } from "../domain/android/androidApplication.js"; -import { appleApplicationProjectionInputSchema } from "../domain/appleApplication.js"; +import { appleApplicationProjectionInputSchema } from "../domain/apple/appleApplication.js"; import { jsonValueSchema, type JsonValue } from "../domain/jsonValue.js"; import type { Logger } from "../logger.js"; import { traceApplicationFeatureInputSchema } from "../domain/javascript/javascriptFeatureTraceSchemas.js"; diff --git a/src/contracts/applicationToolContracts.ts b/src/contracts/applicationToolContracts.ts index 763e6632a1..6ef806c364 100644 --- a/src/contracts/applicationToolContracts.ts +++ b/src/contracts/applicationToolContracts.ts @@ -23,7 +23,7 @@ import { import { appleApplicationProjectionInputSchema, appleApplicationProjectionResultSchema, -} from "../domain/appleApplication.js"; +} from "../domain/apple/appleApplication.js"; import type { ToolContract } from "./toolContracts.js"; import { toolContractMetadata } from "./toolEffects.js"; import { evidenceResultOf } from "./toolOutputSchemas.js"; diff --git a/src/contracts/artifactToolContracts.ts b/src/contracts/artifactToolContracts.ts index bd529d8ba5..85fb8936bc 100644 --- a/src/contracts/artifactToolContracts.ts +++ b/src/contracts/artifactToolContracts.ts @@ -5,8 +5,8 @@ import { artifactOutputSchemas } from "./toolOutputSchemas.js"; import { jsonValueSchema } from "../domain/jsonValue.js"; import { toolContractMetadata } from "./toolEffects.js"; import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js"; -import { appleAssetCatalogInputSchema } from "../domain/appleAssetCatalog.js"; -import { keyedArchiveInputSchema } from "../domain/keyedArchive.js"; +import { appleAssetCatalogInputSchema } from "../domain/apple/appleAssetCatalog.js"; +import { keyedArchiveInputSchema } from "../domain/apple/keyedArchive.js"; /** Exact caller boundary for deterministic artifact inventory. */ export const artifactInventoryInputSchema = z.strictObject({ integrity_policy: z.enum(["fail", "record-and-continue"]).default("fail"), diff --git a/src/contracts/toolOutputSchemaGroups.ts b/src/contracts/toolOutputSchemaGroups.ts index c4ef6b7707..eb0fb000e1 100644 --- a/src/contracts/toolOutputSchemaGroups.ts +++ b/src/contracts/toolOutputSchemaGroups.ts @@ -30,9 +30,9 @@ import { } from "../domain/nativeInspection.js"; import { artifactExtractionResultSchema } from "../domain/artifactGraph.js"; import { artifactInspectionResultSchema } from "../domain/artifactInspection.js"; -import { interfaceBuilderAnalysisSchema } from "../domain/interfaceBuilderGraph.js"; -import { keyedArchiveResultSchema } from "../domain/keyedArchive.js"; -import { appleAssetCatalogResultSchema } from "../domain/appleAssetCatalog.js"; +import { interfaceBuilderAnalysisSchema } from "../domain/apple/interfaceBuilderGraph.js"; +import { keyedArchiveResultSchema } from "../domain/apple/keyedArchive.js"; +import { appleAssetCatalogResultSchema } from "../domain/apple/appleAssetCatalog.js"; import { managedArtifactInspectionSchema, managedMemberInspectionSchema, diff --git a/src/domain/appleApplication.test.ts b/src/domain/apple/appleApplication.test.ts similarity index 98% rename from src/domain/appleApplication.test.ts rename to src/domain/apple/appleApplication.test.ts index 47c45a7462..ea5419dc9c 100644 --- a/src/domain/appleApplication.test.ts +++ b/src/domain/apple/appleApplication.test.ts @@ -3,9 +3,9 @@ import { createHash } from "node:crypto"; import { describe, expect, it } from "vitest"; import { projectAppleApplication } from "./appleApplication.js"; -import { canonicalDigest } from "./comparisonSemantics.js"; -import { createEvidence, type Evidence } from "./evidence.js"; -import { jsonValueSchema } from "./jsonValue.js"; +import { canonicalDigest } from "../comparisonSemantics.js"; +import { createEvidence, type Evidence } from "../evidence.js"; +import { jsonValueSchema } from "../jsonValue.js"; type EntryKind = "file" | "directory" | "symlink"; type RootFormat = "ipa" | "zip" | "dmg" | "directory" | "asar"; diff --git a/src/domain/appleApplication.ts b/src/domain/apple/appleApplication.ts similarity index 98% rename from src/domain/appleApplication.ts rename to src/domain/apple/appleApplication.ts index 42bc970b6e..bb88a8c319 100644 --- a/src/domain/appleApplication.ts +++ b/src/domain/apple/appleApplication.ts @@ -14,10 +14,10 @@ import { platformsOf, type AppleInventoryEntry, } from "./appleBundleAnatomy.js"; -import { parseArtifactInventoryEvidence } from "./artifactInventoryEvidence.js"; -import { evidenceSchema } from "./evidence.js"; -import { digestSchema } from "./../domain/digests.js"; -import { prefixedDigestSchema } from "./../domain/digests.js"; +import { parseArtifactInventoryEvidence } from "../artifactInventoryEvidence.js"; +import { evidenceSchema } from "../evidence.js"; +import { digestSchema } from "../digests.js"; +import { prefixedDigestSchema } from "../digests.js"; const evidenceIdSchema = prefixedDigestSchema("ev"); const pathSchema = z.string().min(1); diff --git a/src/domain/appleAssetCatalog.test.ts b/src/domain/apple/appleAssetCatalog.test.ts similarity index 100% rename from src/domain/appleAssetCatalog.test.ts rename to src/domain/apple/appleAssetCatalog.test.ts diff --git a/src/domain/appleAssetCatalog.ts b/src/domain/apple/appleAssetCatalog.ts similarity index 98% rename from src/domain/appleAssetCatalog.ts rename to src/domain/apple/appleAssetCatalog.ts index 12439fce0a..2954ebda8e 100644 --- a/src/domain/appleAssetCatalog.ts +++ b/src/domain/apple/appleAssetCatalog.ts @@ -1,7 +1,7 @@ import { z } from "zod"; -import { jsonValueSchema } from "./jsonValue.js"; -import { AnalysisOutputError } from "./analysisErrorCore.js"; +import { jsonValueSchema } from "../jsonValue.js"; +import { AnalysisOutputError } from "../analysisErrorCore.js"; /** Caller-controlled page bounds for compiled Apple asset metadata. */ export const appleAssetCatalogInputSchema = z.strictObject({ diff --git a/src/domain/appleBundleAnatomy.ts b/src/domain/apple/appleBundleAnatomy.ts similarity index 99% rename from src/domain/appleBundleAnatomy.ts rename to src/domain/apple/appleBundleAnatomy.ts index f98def7c64..224c5ff49e 100644 --- a/src/domain/appleBundleAnatomy.ts +++ b/src/domain/apple/appleBundleAnatomy.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { digestSchema, prefixedDigestSchema } from "./digests.js"; +import { digestSchema, prefixedDigestSchema } from "../digests.js"; const pathSchema = z.string().min(1); diff --git a/src/domain/interfaceBuilderGraph.test.ts b/src/domain/apple/interfaceBuilderGraph.test.ts similarity index 100% rename from src/domain/interfaceBuilderGraph.test.ts rename to src/domain/apple/interfaceBuilderGraph.test.ts diff --git a/src/domain/interfaceBuilderGraph.ts b/src/domain/apple/interfaceBuilderGraph.ts similarity index 99% rename from src/domain/interfaceBuilderGraph.ts rename to src/domain/apple/interfaceBuilderGraph.ts index 2e882ab26a..22d8a544b8 100644 --- a/src/domain/interfaceBuilderGraph.ts +++ b/src/domain/apple/interfaceBuilderGraph.ts @@ -10,7 +10,7 @@ import { nativeInvestigationGraphSchema, nativeInvestigationNodeSchema, nativeInvestigationTraceLimitsSchema, -} from "./nativeInvestigationGraph.js"; +} from "../nativeInvestigationGraph.js"; export { parseInterfaceBuilderRecords } from "./interfaceBuilderKeyedArchive.js"; diff --git a/src/domain/interfaceBuilderKeyedArchive.ts b/src/domain/apple/interfaceBuilderKeyedArchive.ts similarity index 99% rename from src/domain/interfaceBuilderKeyedArchive.ts rename to src/domain/apple/interfaceBuilderKeyedArchive.ts index 602392c226..d1ee5c3ea1 100644 --- a/src/domain/interfaceBuilderKeyedArchive.ts +++ b/src/domain/apple/interfaceBuilderKeyedArchive.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { jsonValueSchema } from "./jsonValue.js"; +import { jsonValueSchema } from "../jsonValue.js"; const recordSchema = z.record(z.string(), z.unknown()); diff --git a/src/domain/keyedArchive.ts b/src/domain/apple/keyedArchive.ts similarity index 99% rename from src/domain/keyedArchive.ts rename to src/domain/apple/keyedArchive.ts index 32e855f187..2fc6a792f9 100644 --- a/src/domain/keyedArchive.ts +++ b/src/domain/apple/keyedArchive.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { jsonValueSchema, type JsonValue } from "./jsonValue.js"; +import { jsonValueSchema, type JsonValue } from "../jsonValue.js"; /** Select one archive within the active bundle and optionally one named root. */ export const keyedArchiveInputSchema = z.strictObject({ diff --git a/src/domain/plistValue.test.ts b/src/domain/apple/plistValue.test.ts similarity index 100% rename from src/domain/plistValue.test.ts rename to src/domain/apple/plistValue.test.ts diff --git a/src/domain/plistValue.ts b/src/domain/apple/plistValue.ts similarity index 97% rename from src/domain/plistValue.ts rename to src/domain/apple/plistValue.ts index 6c427a8adb..dc6e4d0ea4 100644 --- a/src/domain/plistValue.ts +++ b/src/domain/apple/plistValue.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import type { JsonValue } from "./jsonValue.js"; +import type { JsonValue } from "../jsonValue.js"; const MAX_PLIST_DEPTH = 128; diff --git a/src/domain/nativeInvestigationGraph.test.ts b/src/domain/nativeInvestigationGraph.test.ts index f11aef0207..160d296601 100644 --- a/src/domain/nativeInvestigationGraph.test.ts +++ b/src/domain/nativeInvestigationGraph.test.ts @@ -8,7 +8,7 @@ import { import { buildInterfaceBuilderAnalysis, interfaceBuilderLimitsSchema, -} from "./interfaceBuilderGraph.js"; +} from "./apple/interfaceBuilderGraph.js"; const evidence = [ { diff --git a/src/native/parsers/plist.ts b/src/native/parsers/plist.ts index 977e7909aa..b27f67b1ee 100644 --- a/src/native/parsers/plist.ts +++ b/src/native/parsers/plist.ts @@ -5,7 +5,7 @@ import type { JsonValue } from "../../domain/jsonValue.js"; import { projectPlistValue, type ProjectedPlistValue, -} from "../../domain/plistValue.js"; +} from "../../domain/apple/plistValue.js"; import { omitPrototypeKeys, omittedPrototypeKeysLimitation, diff --git a/src/server/registerApplicationTools/projectMobileApplicationGraph.ts b/src/server/registerApplicationTools/projectMobileApplicationGraph.ts index 573eee331c..cac99a6386 100644 --- a/src/server/registerApplicationTools/projectMobileApplicationGraph.ts +++ b/src/server/registerApplicationTools/projectMobileApplicationGraph.ts @@ -1,7 +1,7 @@ import type { McpServer } from "@modelcontextprotocol/server"; import { projectAndroidApplicationEvidence } from "../../application/android/AndroidApplicationService.js"; -import { projectAppleApplicationEvidence } from "../../application/AppleApplicationService.js"; +import { projectAppleApplicationEvidence } from "../../application/apple/AppleApplicationService.js"; import { APPLICATION_TOOL_CONTRACTS, applicationToolContract, diff --git a/tests/boundary/filesystem/interfaceBuilderBundle.test.ts b/tests/boundary/filesystem/interfaceBuilderBundle.test.ts index df21730035..a669842728 100644 --- a/tests/boundary/filesystem/interfaceBuilderBundle.test.ts +++ b/tests/boundary/filesystem/interfaceBuilderBundle.test.ts @@ -7,8 +7,8 @@ import { promisify } from "node:util"; import { buildBinary } from "plist"; import { describe, expect, it } from "vitest"; -import { analyzeInterfaceBuilderBundle } from "../../../src/application/InterfaceBuilderAnalysis.js"; -import { encodeNibArchiveFixture } from "../../../src/artifacts/NibArchive.fixture.js"; +import { analyzeInterfaceBuilderBundle } from "../../../src/artifacts/apple/InterfaceBuilderAnalysis.js"; +import { encodeNibArchiveFixture } from "../../../src/artifacts/apple/NibArchive.fixture.js"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; const compile = promisify(execFile); diff --git a/tests/boundary/filesystem/nativeArtifactGoldens.test.ts b/tests/boundary/filesystem/nativeArtifactGoldens.test.ts index 30ea714700..7387b2aeb9 100644 --- a/tests/boundary/filesystem/nativeArtifactGoldens.test.ts +++ b/tests/boundary/filesystem/nativeArtifactGoldens.test.ts @@ -1,10 +1,10 @@ import { readFile } from "node:fs/promises"; import { describe, expect, it } from "vitest"; -import { decodeKeyedArchiveBytes } from "../../../src/artifacts/KeyedArchiveReader.js"; +import { decodeKeyedArchiveBytes } from "../../../src/artifacts/apple/KeyedArchiveReader.js"; import { parseAppleAssetCatalogRecords, projectAppleAssetCatalogPage, -} from "../../../src/domain/appleAssetCatalog.js"; +} from "../../../src/domain/apple/appleAssetCatalog.js"; const golden = (path: string) => new URL(`../../fixtures/golden/${path}`, import.meta.url); diff --git a/tests/boundary/filesystem/nibNativeHierarchy.test.ts b/tests/boundary/filesystem/nibNativeHierarchy.test.ts index 83b025b79b..360b7e190f 100644 --- a/tests/boundary/filesystem/nibNativeHierarchy.test.ts +++ b/tests/boundary/filesystem/nibNativeHierarchy.test.ts @@ -6,8 +6,8 @@ import { promisify } from "node:util"; import { describe, expect, it } from "vitest"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; -import { decodeNibArchive } from "../../../src/artifacts/NibArchive.js"; -import { analyzeInterfaceBuilderBundle } from "../../../src/application/InterfaceBuilderAnalysis.js"; +import { decodeNibArchive } from "../../../src/artifacts/apple/NibArchive.js"; +import { analyzeInterfaceBuilderBundle } from "../../../src/artifacts/apple/InterfaceBuilderAnalysis.js"; const compile = promisify(execFile); diff --git a/tests/boundary/mcp/artifactMcp.inlineInventory.test.ts b/tests/boundary/mcp/artifactMcp.inlineInventory.test.ts index b879b7bd95..b099a3825d 100644 --- a/tests/boundary/mcp/artifactMcp.inlineInventory.test.ts +++ b/tests/boundary/mcp/artifactMcp.inlineInventory.test.ts @@ -7,7 +7,7 @@ import { expect, it } from "vitest"; import { z } from "zod"; import { parseConfig } from "../../../src/config.js"; import { createBinarySession } from "../../../src/application/runtime.js"; -import { keyedArchiveResultSchema } from "../../../src/domain/keyedArchive.js"; +import { keyedArchiveResultSchema } from "../../../src/domain/apple/keyedArchive.js"; import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js"; import { createTestBinarySession } from "../../fixtures/binarySession.js"; diff --git a/tests/boundary/providers/native/keyedArchiveEncoding.test.ts b/tests/boundary/providers/native/keyedArchiveEncoding.test.ts index 31db384c1f..c32a6e0372 100644 --- a/tests/boundary/providers/native/keyedArchiveEncoding.test.ts +++ b/tests/boundary/providers/native/keyedArchiveEncoding.test.ts @@ -5,7 +5,7 @@ import { join } from "node:path"; import { buildBinary, parse } from "plist"; import { expect, it } from "vitest"; -import { inspectBundleKeyedArchive } from "../../../../src/artifacts/KeyedArchiveReader.js"; +import { inspectBundleKeyedArchive } from "../../../../src/artifacts/apple/KeyedArchiveReader.js"; import { nativeFixture } from "../../../fixtures/nativeCommands.js"; import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js"; diff --git a/tests/composition/analysis-sessions/appleApplication.test.ts b/tests/composition/analysis-sessions/appleApplication.test.ts index 3f38ec9ae2..8f870ad47b 100644 --- a/tests/composition/analysis-sessions/appleApplication.test.ts +++ b/tests/composition/analysis-sessions/appleApplication.test.ts @@ -16,9 +16,9 @@ import { requireSuccessfulProjection, } from "../../support/applicationSessionFixture.js"; -import { projectAppleApplicationEvidence } from "../../../src/application/AppleApplicationService.js"; +import { projectAppleApplicationEvidence } from "../../../src/application/apple/AppleApplicationService.js"; import { runProviderAnalysis } from "../../../src/application/DirectAnalysis.js"; -import { appleApplicationProjectionResultSchema } from "../../../src/domain/appleApplication.js"; +import { appleApplicationProjectionResultSchema } from "../../../src/domain/apple/appleApplication.js"; import { parseEvidence } from "../../../src/domain/evidence.js"; // Real ZIP entries cross the former component and bridge-candidate limits. diff --git a/tests/evaluation/moduleBoundaries.test.ts b/tests/evaluation/moduleBoundaries.test.ts index b9b1146d81..4b808f331a 100644 --- a/tests/evaluation/moduleBoundaries.test.ts +++ b/tests/evaluation/moduleBoundaries.test.ts @@ -272,3 +272,22 @@ describe("test lane import boundaries", () => { if (!allowed) expect(result.stdout).toContain("no-restricted-imports"); }); }); + +describe("Apple artifact producer ownership", () => { + it.each([ + ["../../application/Workflow.js", false], + ["../../composition/android.js", false], + ["../../cli.js", false], + ["../../domain/apple/plistValue.js", true], + ["../DirectoryArtifactReader.js", true], + ])("checks the producer dependency %s", (dependency, allowed) => { + const violations = inspectModuleBoundaries( + "src/artifacts/apple/probe.ts", + `import type { Value } from ${JSON.stringify(dependency)};`, + process.cwd(), + ); + + expect(violations.length === 0).toBe(allowed); + if (!allowed) expect(violations[0]?.boundary).toBe("artifact-acquisition"); + }); +}); diff --git a/turbo.json b/turbo.json index 086d4db29e..62e4f0adeb 100644 --- a/turbo.json +++ b/turbo.json @@ -111,6 +111,8 @@ "scripts/lib/*.mjs", "scripts/verify/managed/*.mjs", "scripts/fixtures/managed/*.mjs", + "scripts/verify/apple/*.mjs", + "scripts/fixtures/apple/*.mjs", "src/generated*.ts", "src/contracts/**/*.ts", "docs/**",