diff --git a/docs/architecture.mermaid b/docs/architecture.mermaid
index f4835fdb2..b4fc6c5b0 100644
--- a/docs/architecture.mermaid
+++ b/docs/architecture.mermaid
@@ -30,7 +30,7 @@ graph TD
GHIDRA["src/ghidra/
Ghidra discovery, profile & function analysis
snapshot, Unix/Windows transport, bounded lifecycle"]
IDA["src/ida/
Upstream MCP contract adaptation
live GUI binding or owned headless database"]
IDA_MCP["External ida-pro-mcp
GUI proxy or database supervisor
upstream installation and engine lifecycle"]
- AUX["src/artifacts/ + src/native/
disjoint artifact and native capabilities"]
+ AUX["src/artifacts/ + src/native/
artifact inventory and extraction
format readers and native capabilities"]
BROWSER["src/browser/
CDP / Playwright capture
captured scripts and native module resolution
execution/: coverage, listener and source attribution"]
JS_CODEC["src/javascript/sourceMaps/
pinned upstream map codec
owned heap-limited Node process, complete point evidence"]
INSPECTOR["src/inspector/
passive V8 Inspector discovery and capture
script and target locations"]
diff --git a/docs/capability-migration.md b/docs/capability-migration.md
index e38761e73..1a757dd82 100644
--- a/docs/capability-migration.md
+++ b/docs/capability-migration.md
@@ -385,6 +385,30 @@ claims. Actual Swift/Xcode, assetutil, native NIB, bundle signing and DMG lifecy
claims require the real Apple lane. Native binary API/value-flow semantics and
shared cross-domain contract aggregates keep their separate owners.
+## Artifact inventory and extraction ownership
+
+`src/artifacts/inventory/` owns format classification, reader selection, inventory
+policy, canonical scanning and artifact graph construction. The shared artifact
+provider and JavaScript reconstruction workflow consume this owner. Snapshot
+semantics remain in `src/domain/artifactInventorySnapshot.ts`.
+
+`src/artifacts/extraction/` owns member selection, integrity checks and transactional
+materialization through the existing readers and safe output tree. Reader cleanup,
+cancellation, rollback, archive containment and caller-visible results retain their
+existing behavior. Acquisition guards reject imports from these producer owners
+into application workflows, production composition or CLI/MCP adapters.
+
+`src/application/artifacts/ArtifactExtractionDestination.ts` owns the caller's
+default temporary output-root choice for both CLI and MCP. The adapters pass this
+destination to the existing provider operation; format handling and member writes
+remain in the artifact owner.
+
+Add format-specific acquisition behavior beside the inventory readers and exercise
+its actual producer representation in filesystem boundary tests. Add caller
+workflow behavior in the application owner and verify both adapters. The installed
+package lane checks inventory identity and extraction through CLI and MCP; the
+real Apple bundle lane separately establishes DMG mount and detach behavior.
+
## Binary production composition closure
`src/composition/binary.ts` is the shared production owner for deep candidate
diff --git a/scripts/lib/module-boundaries.mjs b/scripts/lib/module-boundaries.mjs
index 05b12b85f..b50050d79 100644
--- a/scripts/lib/module-boundaries.mjs
+++ b/scripts/lib/module-boundaries.mjs
@@ -78,6 +78,8 @@ const failedBoundary = (file, target) => {
if (
(file.startsWith("src/artifacts/javascript/") ||
file.startsWith("src/artifacts/apple/") ||
+ file.startsWith("src/artifacts/inventory/") ||
+ file.startsWith("src/artifacts/extraction/") ||
/^src\/artifacts\/ArtifactHash\.(?:js|ts)$/u.test(file)) &&
(["application", "composition", "server", "cli", "main"].includes(
targetLayer,
diff --git a/scripts/verify-package-mcp.mjs b/scripts/verify-package-mcp.mjs
index a4831d825..3b5be1b5d 100644
--- a/scripts/verify-package-mcp.mjs
+++ b/scripts/verify-package-mcp.mjs
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
import { join } from "node:path";
import { execFile } from "node:child_process";
import { promisify } from "node:util";
+import { readFile, rm } from "node:fs/promises";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
@@ -167,6 +168,7 @@ const verifyMcpInlineArtifactEvidence = async (
mcpOptions,
);
assert.notEqual(opened.isError, true, JSON.stringify(opened));
+ let outputRoot;
try {
const inspected = await client.callTool(
{ name: "inspect_artifact", arguments: {} },
@@ -212,12 +214,35 @@ const verifyMcpInlineArtifactEvidence = async (
evidence,
);
}
- } finally {
- const closed = await client.callTool(
- { name: "close_binary", arguments: {} },
+ const extracted = await client.callTool(
+ { name: "extract_artifact", arguments: {} },
mcpOptions,
);
- assert.notEqual(closed.isError, true, JSON.stringify(closed));
+ assert.notEqual(extracted.isError, true, JSON.stringify(extracted));
+ const extraction = parseEvidence(extracted.structuredContent?.evidence);
+ assert.deepEqual(
+ extraction.normalized_result,
+ extracted.structuredContent?.result,
+ );
+ const materialized = extracted.structuredContent?.result;
+ assert.equal(typeof materialized?.output_root, "string");
+ outputRoot = materialized.output_root;
+ assert.equal(materialized.containment_verified, true);
+ assert.equal(
+ await readFile(join(outputRoot, "app/main.js"), "utf8"),
+ "main();",
+ );
+ } finally {
+ try {
+ const closed = await client.callTool(
+ { name: "close_binary", arguments: {} },
+ mcpOptions,
+ );
+ assert.notEqual(closed.isError, true, JSON.stringify(closed));
+ } finally {
+ if (outputRoot !== undefined)
+ await rm(outputRoot, { recursive: true, force: true });
+ }
}
};
diff --git a/src/application/ArtifactExtractionDestination.ts b/src/application/artifacts/ArtifactExtractionDestination.ts
similarity index 100%
rename from src/application/ArtifactExtractionDestination.ts
rename to src/application/artifacts/ArtifactExtractionDestination.ts
diff --git a/src/application/javascript/JavaScriptArtifactGraphBuilder.ts b/src/application/javascript/JavaScriptArtifactGraphBuilder.ts
index 6af56f1a7..49f317270 100644
--- a/src/application/javascript/JavaScriptArtifactGraphBuilder.ts
+++ b/src/application/javascript/JavaScriptArtifactGraphBuilder.ts
@@ -1,4 +1,4 @@
-import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
+import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
import {
createJavaScriptApplicationGraph,
type JavaScriptApplicationGraph,
diff --git a/src/application/javascript/JavaScriptArtifactGraphContext.ts b/src/application/javascript/JavaScriptArtifactGraphContext.ts
index 8e398bc77..291dfa46f 100644
--- a/src/application/javascript/JavaScriptArtifactGraphContext.ts
+++ b/src/application/javascript/JavaScriptArtifactGraphContext.ts
@@ -1,4 +1,4 @@
-import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
+import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
import {
completeApplicationCoverage,
partialApplicationCoverage,
diff --git a/src/application/javascript/JavaScriptArtifactGraphStructure.ts b/src/application/javascript/JavaScriptArtifactGraphStructure.ts
index 7a135fdea..039659f89 100644
--- a/src/application/javascript/JavaScriptArtifactGraphStructure.ts
+++ b/src/application/javascript/JavaScriptArtifactGraphStructure.ts
@@ -1,4 +1,4 @@
-import type { ArtifactInventorySnapshot } from "../ArtifactInventory.js";
+import type { ArtifactInventorySnapshot } from "../../artifacts/inventory/ArtifactInventory.js";
import type { ApplicationNode } from "../../domain/javascript/javascriptApplicationGraph.js";
import { completeApplicationCoverage } from "../../domain/javascript/javascriptApplicationEvidenceSchemas.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
diff --git a/src/application/javascript/JavaScriptArtifactReconstruction.ts b/src/application/javascript/JavaScriptArtifactReconstruction.ts
index 0be85beb5..7f14c7898 100644
--- a/src/application/javascript/JavaScriptArtifactReconstruction.ts
+++ b/src/application/javascript/JavaScriptArtifactReconstruction.ts
@@ -12,7 +12,7 @@ import {
javascriptArtifactReconstructionInputSchema,
type JavaScriptArtifactReconstructionInput,
} from "./JavaScriptArtifactReconstructionInput.js";
-import { scanCanonicalArtifactInventory } from "../ArtifactInventory.js";
+import { scanCanonicalArtifactInventory } from "../../artifacts/inventory/ArtifactInventory.js";
import { summarizeElectronBoundaries } from "./ElectronBoundaryAnalysis.js";
import { buildJavaScriptSemanticGraph } from "./JavaScriptSemanticGraphBuilder.js";
import type { ProgressReporter } from "../ProgressReporter.js";
diff --git a/src/artifacts/ArtifactProvider.ts b/src/artifacts/ArtifactProvider.ts
index 54d9d3826..8d4885f48 100644
--- a/src/artifacts/ArtifactProvider.ts
+++ b/src/artifacts/ArtifactProvider.ts
@@ -9,8 +9,8 @@ import {
} from "../application/AnalysisProvider.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 { inventoryArtifact } from "./inventory/ArtifactInventory.js";
+import { extractArtifact } from "./extraction/ArtifactExtraction.js";
import { analyzeInterfaceBuilderBundle } from "./apple/InterfaceBuilderAnalysis.js";
import { analyzeAppleAssetCatalogs } from "./apple/AppleAssetCatalogAnalysis.js";
import {
@@ -33,7 +33,7 @@ import {
} from "./ArtifactProviderMetadata.js";
import { createEvidence } from "../domain/evidence.js";
import { createArtifactInspection } from "../domain/artifactInspection.js";
-import { resolveArtifactIntegrityPolicy } from "../application/ArtifactInventory/policy.js";
+import { resolveArtifactIntegrityPolicy } from "./inventory/policy.js";
/** Read-only inventory and exclusively owned extraction provider. */
export class ArtifactProvider implements AnalysisProvider {
diff --git a/src/application/ArtifactExtraction.ts b/src/artifacts/extraction/ArtifactExtraction.ts
similarity index 92%
rename from src/application/ArtifactExtraction.ts
rename to src/artifacts/extraction/ArtifactExtraction.ts
index 7fc20dae9..57e8a0066 100644
--- a/src/application/ArtifactExtraction.ts
+++ b/src/artifacts/extraction/ArtifactExtraction.ts
@@ -1,29 +1,29 @@
import { lstat, realpath } from "node:fs/promises";
-import { canonicalDigest } from "../domain/comparisonSemantics.js";
-import { AsarArtifactReader } from "../artifacts/AsarArtifactReader.js";
+import { canonicalDigest } from "../../domain/comparisonSemantics.js";
+import { AsarArtifactReader } from "../AsarArtifactReader.js";
import {
ArtifactPathRegistry,
normalizeArtifactPath,
-} from "../artifacts/ArtifactPaths.js";
+} from "../ArtifactPaths.js";
import {
ArtifactReaderFailure,
type ArtifactEntry,
type ArtifactReader,
-} from "../artifacts/ArtifactReader.js";
-import { DirectoryArtifactReader } from "../artifacts/DirectoryArtifactReader.js";
-import { SafeOutputTree } from "../artifacts/SafeOutputTree.js";
-import { ZipArtifactReader } from "../artifacts/ZipArtifactReader.js";
-import { MachOSliceArtifactReader } from "../artifacts/MachOSliceArtifactReader.js";
+} from "../ArtifactReader.js";
+import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
+import { SafeOutputTree } from "../SafeOutputTree.js";
+import { ZipArtifactReader } from "../ZipArtifactReader.js";
+import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
import {
artifactExtractionResultSchema,
type ArtifactExtractionResult,
type ArtifactGraphManifest,
type ArtifactNode,
type ArtifactOccurrence,
-} from "../domain/artifactGraph.js";
-import type { BinaryTarget } from "../domain/binaryTarget.js";
-import { scanArtifactInventory } from "./ArtifactInventory.js";
+} from "../../domain/artifactGraph.js";
+import type { BinaryTarget } from "../../domain/binaryTarget.js";
+import { scanArtifactInventory } from "../inventory/ArtifactInventory.js";
/** Local extraction input with the output root chosen by the adapter. */
export interface ArtifactExtractionInput {
diff --git a/src/application/ArtifactGraphConstruction.test.ts b/src/artifacts/inventory/ArtifactGraphConstruction.test.ts
similarity index 100%
rename from src/application/ArtifactGraphConstruction.test.ts
rename to src/artifacts/inventory/ArtifactGraphConstruction.test.ts
diff --git a/src/application/ArtifactGraphConstruction.ts b/src/artifacts/inventory/ArtifactGraphConstruction.ts
similarity index 97%
rename from src/application/ArtifactGraphConstruction.ts
rename to src/artifacts/inventory/ArtifactGraphConstruction.ts
index 187d5d677..a0d1d5e1c 100644
--- a/src/application/ArtifactGraphConstruction.ts
+++ b/src/artifacts/inventory/ArtifactGraphConstruction.ts
@@ -1,13 +1,13 @@
-import { canonicalDigest } from "../domain/comparisonSemantics.js";
-import type { ArtifactEntry } from "../artifacts/ArtifactReader.js";
+import { canonicalDigest } from "../../domain/comparisonSemantics.js";
+import type { ArtifactEntry } from "../ArtifactReader.js";
import type {
ArtifactCommand,
ArtifactEdge,
ArtifactNode,
ArtifactOccurrence,
-} from "../domain/artifactGraph.js";
-import { zipPackageFormatForPath } from "../domain/zipPackageFormat.js";
-import { mzWindowsHeaderOffset, parseDosMzHeader } from "../domain/dosMz.js";
+} from "../../domain/artifactGraph.js";
+import { zipPackageFormatForPath } from "../../domain/zipPackageFormat.js";
+import { mzWindowsHeaderOffset, parseDosMzHeader } from "../../domain/dosMz.js";
/** Mutable internal occurrence used until root-bound IDs are known. */
export interface MutableOccurrence {
diff --git a/src/application/ArtifactInventory.ts b/src/artifacts/inventory/ArtifactInventory.ts
similarity index 75%
rename from src/application/ArtifactInventory.ts
rename to src/artifacts/inventory/ArtifactInventory.ts
index a7b5b181f..3b121766b 100644
--- a/src/application/ArtifactInventory.ts
+++ b/src/artifacts/inventory/ArtifactInventory.ts
@@ -3,22 +3,22 @@ import { realpath } from "node:fs/promises";
import {
artifactInventoryResultSchema,
type ArtifactInventoryResult,
-} from "../domain/artifactGraph.js";
-import { abortIfNeeded } from "../artifacts/ArtifactHash.js";
-import { scanCanonicalArtifactInventory } from "./ArtifactInventory/scanCanonical.js";
+} from "../../domain/artifactGraph.js";
+import { abortIfNeeded } from "../ArtifactHash.js";
+import { scanCanonicalArtifactInventory } from "./scanCanonical.js";
import type {
ArtifactIntegrityPolicy,
ArtifactInventoryOptions,
ArtifactInventorySnapshot,
-} from "./ArtifactInventory/types.js";
+} from "./types.js";
-export { scanCanonicalArtifactInventory } from "./ArtifactInventory/scanCanonical.js";
+export { scanCanonicalArtifactInventory } from "./scanCanonical.js";
export type {
ArtifactIntegrityPolicy,
ArtifactInventoryOptions,
ArtifactInventorySnapshot,
-} from "./ArtifactInventory/types.js";
+} from "./types.js";
/** Inventory one local artifact and return every graph collection inline. */
export const inventoryArtifact = async (
diff --git a/src/application/ArtifactInventory/classify.ts b/src/artifacts/inventory/classify.ts
similarity index 88%
rename from src/application/ArtifactInventory/classify.ts
rename to src/artifacts/inventory/classify.ts
index 36e953712..421772346 100644
--- a/src/application/ArtifactInventory/classify.ts
+++ b/src/artifacts/inventory/classify.ts
@@ -1,7 +1,7 @@
import { open } from "node:fs/promises";
-import { classifyArtifactContent } from "../ArtifactGraphConstruction.js";
-import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../../artifacts/ArtifactHash.js";
+import { classifyArtifactContent } from "./ArtifactGraphConstruction.js";
+import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../ArtifactHash.js";
import type { ArtifactNode } from "../../domain/artifactGraph.js";
import {
hasZipSignature,
diff --git a/src/application/ArtifactInventory/policy.ts b/src/artifacts/inventory/policy.ts
similarity index 100%
rename from src/application/ArtifactInventory/policy.ts
rename to src/artifacts/inventory/policy.ts
diff --git a/src/application/ArtifactInventory/reader.ts b/src/artifacts/inventory/reader.ts
similarity index 74%
rename from src/application/ArtifactInventory/reader.ts
rename to src/artifacts/inventory/reader.ts
index f593acba0..18a0b2769 100644
--- a/src/application/ArtifactInventory/reader.ts
+++ b/src/artifacts/inventory/reader.ts
@@ -1,9 +1,9 @@
-import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
-import type { ArtifactReader } from "../../artifacts/ArtifactReader.js";
-import { DirectoryArtifactReader } from "../../artifacts/DirectoryArtifactReader.js";
-import { MachOSliceArtifactReader } from "../../artifacts/MachOSliceArtifactReader.js";
-import { NativeDmgArtifactReader } from "../../artifacts/NativeDmgArtifactReader.js";
-import { ZipArtifactReader } from "../../artifacts/ZipArtifactReader.js";
+import { AsarArtifactReader } from "../AsarArtifactReader.js";
+import type { ArtifactReader } from "../ArtifactReader.js";
+import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
+import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
+import { NativeDmgArtifactReader } from "../NativeDmgArtifactReader.js";
+import { ZipArtifactReader } from "../ZipArtifactReader.js";
import type { ArtifactNode } from "../../domain/artifactGraph.js";
export const createReader = async (
diff --git a/src/application/ArtifactInventory/scanCanonical.ts b/src/artifacts/inventory/scanCanonical.ts
similarity index 98%
rename from src/application/ArtifactInventory/scanCanonical.ts
rename to src/artifacts/inventory/scanCanonical.ts
index b02005394..2a746343d 100644
--- a/src/application/ArtifactInventory/scanCanonical.ts
+++ b/src/artifacts/inventory/scanCanonical.ts
@@ -5,7 +5,7 @@ import type { Stats } from "node:fs";
import {
ArtifactReaderFailure,
type ArtifactReader,
-} from "../../artifacts/ArtifactReader.js";
+} from "../ArtifactReader.js";
import {
artifactInventoryResultSchema,
type ArtifactInventoryResult,
@@ -20,10 +20,10 @@ import {
rekeyOccurrences,
rootOccurrenceFor,
type MutableOccurrence,
-} from "../ArtifactGraphConstruction.js";
+} from "./ArtifactGraphConstruction.js";
import { canonicalDigest } from "../../domain/comparisonSemantics.js";
import { classifyRoot } from "./classify.js";
-import { hashReadable, type HashResult } from "../../artifacts/ArtifactHash.js";
+import { hashReadable, type HashResult } from "../ArtifactHash.js";
import { createReader, inventoryLimitations } from "./reader.js";
import {
scanReader,
diff --git a/src/application/ArtifactInventory/scanReader.ts b/src/artifacts/inventory/scanReader.ts
similarity index 96%
rename from src/application/ArtifactInventory/scanReader.ts
rename to src/artifacts/inventory/scanReader.ts
index fe24fe408..136f527b4 100644
--- a/src/application/ArtifactInventory/scanReader.ts
+++ b/src/artifacts/inventory/scanReader.ts
@@ -3,13 +3,13 @@ import { isAbsolute } from "node:path";
import {
ArtifactPathRegistry,
normalizeArtifactPath,
-} from "../../artifacts/ArtifactPaths.js";
+} from "../ArtifactPaths.js";
import {
ArtifactReaderFailure,
type ArtifactEntry,
type ArtifactReader,
-} from "../../artifacts/ArtifactReader.js";
-import { AsarArtifactReader } from "../../artifacts/AsarArtifactReader.js";
+} from "../ArtifactReader.js";
+import { AsarArtifactReader } from "../AsarArtifactReader.js";
import type { ArtifactNode } from "../../domain/artifactGraph.js";
import {
classifyArtifactContent,
@@ -17,12 +17,12 @@ import {
createOccurrence,
nearestParent,
type MutableOccurrence,
-} from "../ArtifactGraphConstruction.js";
+} from "./ArtifactGraphConstruction.js";
import {
STRICT_INTEGRITY_POLICY,
type ArtifactIntegrityPolicy,
} from "./types.js";
-import { hashReadable } from "../../artifacts/ArtifactHash.js";
+import { hashReadable } from "../ArtifactHash.js";
export interface PendingIntegrityContradiction {
readonly logicalPath: string;
diff --git a/src/application/ArtifactInventory/types.ts b/src/artifacts/inventory/types.ts
similarity index 100%
rename from src/application/ArtifactInventory/types.ts
rename to src/artifacts/inventory/types.ts
diff --git a/src/cli/artifactCommands.ts b/src/cli/artifactCommands.ts
index 4681608e0..6dc93f7ec 100644
--- a/src/cli/artifactCommands.ts
+++ b/src/cli/artifactCommands.ts
@@ -1,7 +1,7 @@
import { z } from "incur";
import { runProviderAnalysis } from "../composition/directAnalysis.js";
-import { createArtifactExtractionDestination } from "../application/ArtifactExtractionDestination.js";
+import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
import { logCliCommand } from "../cliLogging.js";
import { CLI_COMMANDS } from "../cliCommandNames.js";
import type { Logger } from "../logger.js";
diff --git a/src/server/registerEvidenceTools.ts b/src/server/registerEvidenceTools.ts
index e906bd862..be678179b 100644
--- a/src/server/registerEvidenceTools.ts
+++ b/src/server/registerEvidenceTools.ts
@@ -14,7 +14,7 @@ import { mcpProgressReporter } from "./mcpProgress.js";
import { logToolExecution } from "./toolLogging.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { toCallToolResult } from "./toolResult.js";
-import { createArtifactExtractionDestination } from "../application/ArtifactExtractionDestination.js";
+import { createArtifactExtractionDestination } from "../application/artifacts/ArtifactExtractionDestination.js";
interface EvidenceToolRegistration {
readonly logger: Logger;
diff --git a/tests/boundary/filesystem/artifactComparisonSummary.test.ts b/tests/boundary/filesystem/artifactComparisonSummary.test.ts
index 597af1a89..7879f96aa 100644
--- a/tests/boundary/filesystem/artifactComparisonSummary.test.ts
+++ b/tests/boundary/filesystem/artifactComparisonSummary.test.ts
@@ -3,7 +3,7 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { compareArtifacts } from "../../../src/domain/artifactComparison.js";
import { createEvidence } from "../../../src/domain/evidence.js";
import { jsonValueSchema } from "../../../src/domain/jsonValue.js";
diff --git a/tests/boundary/filesystem/artifactDirectoryIdentity.test.ts b/tests/boundary/filesystem/artifactDirectoryIdentity.test.ts
index bcd1542c4..e87794869 100644
--- a/tests/boundary/filesystem/artifactDirectoryIdentity.test.ts
+++ b/tests/boundary/filesystem/artifactDirectoryIdentity.test.ts
@@ -5,7 +5,7 @@ import { TextReader, Uint8ArrayWriter, ZipWriter } from "@zip.js/zip.js";
import { describe, expect, it } from "vitest";
import { canonicalDigest } from "../../../src/domain/comparisonSemantics.js";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { compareArtifacts } from "../../../src/domain/artifactComparison.js";
import type { ArtifactInventoryResult } from "../../../src/domain/artifactGraph.js";
import { createEvidence } from "../../../src/domain/evidence.js";
diff --git a/tests/boundary/filesystem/artifactInventoryEntryOrder.test.ts b/tests/boundary/filesystem/artifactInventoryEntryOrder.test.ts
index ba7add1b4..6d106e335 100644
--- a/tests/boundary/filesystem/artifactInventoryEntryOrder.test.ts
+++ b/tests/boundary/filesystem/artifactInventoryEntryOrder.test.ts
@@ -4,7 +4,7 @@ import { join } from "node:path";
import { createPackage } from "@electron/asar";
import { describe, expect, it } from "vitest";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import {
artifactOccurrenceAt,
artifactParentPaths,
diff --git a/tests/boundary/filesystem/artifactInventorySnapshot.test.ts b/tests/boundary/filesystem/artifactInventorySnapshot.test.ts
index 5feec925f..bd0201d67 100644
--- a/tests/boundary/filesystem/artifactInventorySnapshot.test.ts
+++ b/tests/boundary/filesystem/artifactInventorySnapshot.test.ts
@@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
-import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
+import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
describe("artifact inventory snapshot", () => {
it("retains the complete scan after the source directory changes", async () => {
diff --git a/tests/boundary/filesystem/artifactMzInventory.test.ts b/tests/boundary/filesystem/artifactMzInventory.test.ts
index d1ae2ef1d..c3fd44005 100644
--- a/tests/boundary/filesystem/artifactMzInventory.test.ts
+++ b/tests/boundary/filesystem/artifactMzInventory.test.ts
@@ -3,10 +3,10 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
-import { classifyArtifactContent } from "../../../src/application/ArtifactGraphConstruction.js";
-import { classifyRoot } from "../../../src/application/ArtifactInventory/classify.js";
+import { classifyArtifactContent } from "../../../src/artifacts/inventory/ArtifactGraphConstruction.js";
+import { classifyRoot } from "../../../src/artifacts/inventory/classify.js";
import { ARTIFACT_CLASSIFICATION_PREFIX_BYTES } from "../../../src/artifacts/ArtifactHash.js";
-import { scanCanonicalArtifactInventory } from "../../../src/application/ArtifactInventory/scanCanonical.js";
+import { scanCanonicalArtifactInventory } from "../../../src/artifacts/inventory/scanCanonical.js";
import { targetFormatSchema } from "../../../src/contracts/toolOutputSchemaPrimitives.js";
import { artifactInventoryResultSchema } from "../../../src/domain/artifactGraph.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
diff --git a/tests/boundary/filesystem/asarInventoryContainment.test.ts b/tests/boundary/filesystem/asarInventoryContainment.test.ts
index 703fa9f8a..6e1f02133 100644
--- a/tests/boundary/filesystem/asarInventoryContainment.test.ts
+++ b/tests/boundary/filesystem/asarInventoryContainment.test.ts
@@ -11,7 +11,7 @@ import {
} from "@zip.js/zip.js";
import { describe, expect, it } from "vitest";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import {
artifactOccurrenceAt,
artifactParentPaths,
diff --git a/tests/boundary/filesystem/asarInventoryFreshness.test.ts b/tests/boundary/filesystem/asarInventoryFreshness.test.ts
index 4d0932935..91cdc81b6 100644
--- a/tests/boundary/filesystem/asarInventoryFreshness.test.ts
+++ b/tests/boundary/filesystem/asarInventoryFreshness.test.ts
@@ -5,7 +5,7 @@ import { buffer } from "node:stream/consumers";
import { createPackage, listPackage, uncache } from "@electron/asar";
import { describe, expect, it } from "vitest";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
diff --git a/tests/boundary/filesystem/asarStreamingAllocation.test.ts b/tests/boundary/filesystem/asarStreamingAllocation.test.ts
index 6a5fac5e4..630091584 100644
--- a/tests/boundary/filesystem/asarStreamingAllocation.test.ts
+++ b/tests/boundary/filesystem/asarStreamingAllocation.test.ts
@@ -14,7 +14,7 @@ import { Readable } from "node:stream";
import { buffer } from "node:stream/consumers";
import { createPackageWithOptions } from "@electron/asar";
import { describe, expect, it } from "vitest";
-import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
+import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
import {
closeAsarHandle,
diff --git a/tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts b/tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts
index da79929f7..1871e59c5 100644
--- a/tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts
+++ b/tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts
@@ -4,7 +4,7 @@ import { join } from "node:path";
import { createPackage } from "@electron/asar";
import { describe, expect, it } from "vitest";
-import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
+import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { readJavaScriptArtifactFiles } from "../../../src/artifacts/javascript/JavaScriptArtifactFiles.js";
import { AsarArtifactReader } from "../../../src/artifacts/AsarArtifactReader.js";
import { DirectoryArtifactReader } from "../../../src/artifacts/DirectoryArtifactReader.js";
diff --git a/tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts b/tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts
index cfab06c6b..3df383e7a 100644
--- a/tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts
+++ b/tests/boundary/filesystem/javascriptArtifactReconstruction.test.ts
@@ -8,7 +8,7 @@ import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { readJavaScriptArtifactFiles } from "../../../src/artifacts/javascript/JavaScriptArtifactFiles.js";
import { reconstructJavaScriptArtifact } from "../../../src/application/javascript/JavaScriptArtifactReconstruction.js";
-import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
+import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import {
type ArtifactEntry,
type ArtifactReader,
diff --git a/tests/boundary/filesystem/zipDetection.test.ts b/tests/boundary/filesystem/zipDetection.test.ts
index a983da496..8ab81112a 100644
--- a/tests/boundary/filesystem/zipDetection.test.ts
+++ b/tests/boundary/filesystem/zipDetection.test.ts
@@ -3,7 +3,7 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
-import { classifyRoot } from "../../../src/application/ArtifactInventory/classify.js";
+import { classifyRoot } from "../../../src/artifacts/inventory/classify.js";
import { parseBinaryTarget } from "../../../src/application/BinaryTargetResolver.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
diff --git a/tests/composition/analysis-sessions/artifactComparison.test.ts b/tests/composition/analysis-sessions/artifactComparison.test.ts
index 36fbfaf52..a3850df20 100644
--- a/tests/composition/analysis-sessions/artifactComparison.test.ts
+++ b/tests/composition/analysis-sessions/artifactComparison.test.ts
@@ -6,7 +6,7 @@ import { describe, expect, it } from "vitest";
import { fragmentInventoryEvidence } from "../../fixtures/artifactEvidence.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
-import { inventoryArtifact } from "../../../src/application/ArtifactInventory.js";
+import { inventoryArtifact } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { artifactInventoryResultSchema } from "../../../src/domain/artifactGraph.js";
import {
artifactComparisonResultSchema,
diff --git a/tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts b/tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
index d4d60e83b..7dad88ab9 100644
--- a/tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
+++ b/tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
@@ -7,7 +7,7 @@ import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { reconstructJavaScriptArtifact } from "../../../src/application/javascript/JavaScriptArtifactReconstruction.js";
-import { scanArtifactInventory } from "../../../src/application/ArtifactInventory.js";
+import { scanArtifactInventory } from "../../../src/artifacts/inventory/ArtifactInventory.js";
import { parseJavaScriptApplicationGraph } from "../../../src/domain/javascript/javascriptApplicationGraph.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { createJavaScriptSemanticGraph } from "../../../src/domain/javascript/javascriptSemanticGraph.js";
diff --git a/tests/evaluation/moduleBoundaries.test.ts b/tests/evaluation/moduleBoundaries.test.ts
index 37c008492..c9b1a25c8 100644
--- a/tests/evaluation/moduleBoundaries.test.ts
+++ b/tests/evaluation/moduleBoundaries.test.ts
@@ -76,7 +76,7 @@ describe("incremental module import boundaries", () => {
["src/contracts/probe.ts", "../composition/android.js", false],
[
"src/artifacts/javascript/probe.ts",
- "../../application/ArtifactInventory.js",
+ "../../application/javascript/JavaScriptArtifactReconstruction.js",
false,
],
[
@@ -87,7 +87,7 @@ describe("incremental module import boundaries", () => {
["src/artifacts/javascript/probe.ts", "../../cli.js", false],
[
"src/artifacts/ArtifactHash.ts",
- "../application/ArtifactInventory/hash.js",
+ "../application/artifacts/ArtifactExtractionDestination.js",
false,
],
[
@@ -111,11 +111,7 @@ describe("incremental module import boundaries", () => {
"../../artifacts/javascript/JavaScriptArtifactReader.js",
true,
],
- [
- "src/application/ArtifactInventory/probe.ts",
- "../../artifacts/AsarArtifactReader.js",
- true,
- ],
+ ["src/artifacts/inventory/probe.ts", "../AsarArtifactReader.js", true],
["src/domain/probe.test.ts", "../composition/firmware.js", false],
["src/application/probe.ts", "../android/JadxProvider.js", false],
["src/application/probe.ts", "../composition/android.js", false],
@@ -329,21 +325,30 @@ describe("test lane import boundaries", () => {
});
});
-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(),
- );
+describe.each(["apple", "inventory", "extraction"])(
+ "%s artifact producer ownership",
+ (owner) => {
+ it.each([
+ ["../../application/Workflow.js", false],
+ ["../../composition/android.js", false],
+ ["../../cli.js", false],
+ ["../../server/registerEvidenceTools.js", false],
+ ["../../main.ts", false],
+ ["../../domain/apple/plistValue.js", true],
+ ["../../domain/artifactInventorySnapshot.js", true],
+ ["../../contracts/artifactGraph.js", true],
+ ["../DirectoryArtifactReader.js", true],
+ ["../ArtifactHash.js", true],
+ ])("checks the producer dependency %s", (dependency, allowed) => {
+ const violations = inspectModuleBoundaries(
+ `src/artifacts/${owner}/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");
- });
-});
+ expect(violations.length === 0).toBe(allowed);
+ if (!allowed)
+ expect(violations[0]?.boundary).toBe("artifact-acquisition");
+ });
+ },
+);