{
 "format": "ac-certificate/2",
 "tool": {
  "name": "architecture-cleaner",
  "version": "0.1.0"
 },
 "repo": "/home/paseo/ac-work/s6/final-immich",
 "base": "311549fdac8d226b3b2c4cb4dde607ef98a8f700",
 "head": "37569c3162ea3effaf7b21797f8e252d7643284e",
 "baseTree": "d074d7315073bf13f5381ba5bbd8f8369d671ec1",
 "headTree": "37262610ad710a9058ce0603a4ddc2159dcb7574",
 "packageRoot": "server",
 "profile": "immich",
 "environment": {
  "checkout": "/home/paseo/ac-targets/immich",
  "node": "v22.23.3",
  "linkedNodeModules": [
   "",
   "packages/plugin-core",
   "packages/plugin-sdk",
   "packages/sdk",
   "server"
  ]
 },
 "workDir": "/home/paseo/ac-work/s6/final/work/step-037-1",
 "pathMap": {
  "moves": 4,
  "unchanged": 3455,
  "editedInPlace": 5,
  "deleted": [],
  "added": [],
  "ambiguousGroups": 0,
  "entries": {
   "server/src/controllers/view.controller.ts": "server/src/modules/view/view.controller.ts",
   "server/src/repositories/view-repository.ts": "server/src/modules/view/view-repository.ts",
   "server/src/services/view.service.spec.ts": "server/src/modules/view/view.service.spec.ts",
   "server/src/services/view.service.ts": "server/src/modules/view/view.service.ts"
  }
 },
 "checks": [
  {
   "id": "K0",
   "title": "Envelope",
   "status": "pass",
   "summary": "inside the envelope: 678 TypeScript vs 3 JavaScript sources under server; no automock, nested package scope, symlink, same-stem pair or unreadable runner config around 4 moved files",
   "metrics": {
    "moves": 4,
    "baseTypeScriptFiles": 678,
    "baseJavaScriptFiles": 3,
    "headTypeScriptFiles": 678,
    "headJavaScriptFiles": 3
   },
   "violations": [],
   "findings": [],
   "durationMs": 5269
  },
  {
   "id": "K1",
   "title": "Move-set integrity",
   "status": "pass",
   "summary": "4 moves, 5 files edited in place, nothing added or deleted",
   "metrics": {
    "moves": 4,
    "unchanged": 3455,
    "editedInPlace": 5,
    "deleted": 0,
    "added": 0,
    "copies": 0,
    "inertAdditions": 0
   },
   "violations": [],
   "findings": [],
   "durationMs": 2219
  },
  {
   "id": "K2",
   "title": "Byte-span confinement",
   "status": "pass",
   "summary": "7 specifier spans changed in 7 files; every other byte identical",
   "metrics": {
    "comparedFiles": 7,
    "editedFiles": 7,
    "changedSpans": 7
   },
   "violations": [],
   "findings": [],
   "durationMs": 715
  },
  {
   "id": "K3a",
   "title": "Resolution identity under TypeScript",
   "status": "pass",
   "summary": "6647 sites in 1100 files resolve to map(base) under every program (458 files in several); 7 rewritten specifiers keep their form",
   "metrics": {
    "files": 1100,
    "sites": 6647,
    "resolutions": 9636,
    "multiProgramFiles": 458,
    "rewrittenSpecifiers": 7,
    "typeDirectives": 13,
    "implicitImports": 0,
    "unextractedSites": 0,
    "addedFiles": 0,
    "deletedFiles": 0,
    "resolutionMismatches": 0,
    "formChanges": 0,
    "contextChanges": 0,
    "typeDirectiveMismatches": 0,
    "workspaceLinks": 0,
    "virtualModuleSplits": 0,
    "unresolvedMoves": 0,
    "unmodeledResolutions": 0
   },
   "violations": [],
   "findings": [],
   "durationMs": 1733
  },
  {
   "id": "K3b",
   "title": "Resolution identity under the test runner",
   "status": "pass",
   "summary": "vitest 4.1.11: 4837 sites in 672 files resolve to map(base)",
   "metrics": {
    "runner": "vitest",
    "runnerVersion": "4.1.11",
    "projects": "server:unit",
    "sites": 4837,
    "files": 672,
    "dangling": 0,
    "retargeted": 0,
    "newlyResolved": 0,
    "unresolvedTextChanged": 0,
    "mockChanged": 0,
    "addedDangling": 0,
    "outsideRoots": 0,
    "outsideProjectRoot": 0,
    "addedFiles": 0
   },
   "violations": [],
   "findings": [],
   "durationMs": 8483
  },
  {
   "id": "K3c",
   "title": "Resolution identity under the runtime",
   "status": "pass",
   "summary": "6192 runtime sites resolve to map(base) under nest-cli/emit (3442 rewritten by the build)",
   "metrics": {
    "runtimes": "nest-cli/emit",
    "runtimeEvidence": "nest-cli/emit: package.json scripts.start:dev: nest start --watch --; package.json scripts.start:debug: nest start --debug 0.0.0.0:9230 --watch --; server/bin/start.sh: exec node --no-warnings \"${SERVER_HOME}/dist/main.js\" \"$@\"",
    "modeled": "nest-cli/emit",
    "notModeled": "",
    "subpathImports": false,
    "emitModel": "in place: each source at its own path with the runtime extension (.ts->.js, .mts->.mjs, .cts->.cjs), as with a fixed rootDir; outDir links to rootDir",
    "node": "v24.21.0",
    "nestCli": "12.0.6",
    "files": 1099,
    "addedFiles": 0,
    "unresolvedInAdded": 0,
    "comparedSites": 6192,
    "rewrittenByBuild": 3442,
    "unresolvedInBase": 1453,
    "deferredSites": 0,
    "aliasSitesBase": 1920,
    "aliasSitesHead": 1920,
    "disagreements": 0,
    "violations": 0
   },
   "violations": [],
   "findings": [],
   "run": {
    "skeletonMs": 1663,
    "probeMs": 4191
   },
   "durationMs": 6752
  },
  {
   "id": "K4",
   "title": "Location scan",
   "status": "pass",
   "summary": "4 moved files expose no location; no computed path reaches a change; no old path in code, config or CI (8 findings in docs, comments or ungated coverage settings)",
   "metrics": {
    "movedFilesScanned": 4,
    "movedFileHazards": 0,
    "copiedFileHazards": 0,
    "filesScannedForComputedPaths": 1096,
    "computedPathViolations": 0,
    "textFilesScanned": 3128,
    "oldPathViolations": 0,
    "coverageViolations": 0,
    "coverageFindings": 2,
    "oldPathFindings": 8,
    "globsChecked": 2877,
    "pluginSuffixViolations": 0
   },
   "violations": [],
   "findings": [
    {
     "kind": "opaque-dynamic-load",
     "file": "server/src/repositories/database.repository.ts",
     "detail": "line 510: import(filePath) loads a module by a path K4 can't evaluate"
    },
    {
     "kind": "old-path-in-docs",
     "file": ".github/pull_request_template.md",
     "detail": "line 36: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts)"
    },
    {
     "kind": "old-path-in-docs",
     "file": ".github/pull_request_template.md",
     "detail": "line 37: 'src/repositories/' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/view-repository.ts (moved to server/src/modules/view/view-repository.ts)"
    },
    {
     "kind": "old-path-in-docs",
     "file": ".github/pull_request_template.md",
     "detail": "line 37: 'src/services/' is the directory server/src/services, whose contents change with the move of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts)"
    },
    {
     "kind": "old-path-in-docs",
     "file": "docs/docs/developer/architecture.mdx",
     "detail": "line 60: 'src/repositories' is the directory server/src/repositories, whose contents change with the move of server/src/repositories/view-repository.ts (moved to server/src/modules/view/view-repository.ts)"
    },
    {
     "kind": "old-path-in-docs",
     "file": "docs/docs/developer/architecture.mdx",
     "detail": "line 60: 'src/services' is the directory server/src/services, whose contents change with the move of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts)"
    },
    {
     "kind": "old-path-in-docs",
     "file": "docs/docs/developer/architecture.mdx",
     "detail": "line 64: 'src/controllers' is the directory server/src/controllers, whose contents change with the move of server/src/controllers/view.controller.ts (moved to server/src/modules/view/view.controller.ts)"
    },
    {
     "kind": "coverage-scope",
     "file": "server/test/vitest.config.mjs",
     "detail": "line 19: 'src/services/**' is the glob server/src/services/** whose matches change (2 moved files, e.g. server/src/services/view.service.spec.ts -> server/src/modules/view/view.service.spec.ts) of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts) [config at test.coverage.include]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes)"
    },
    {
     "kind": "coverage-scope",
     "file": "server/test/vitest.config.mjs",
     "detail": "line 21: 'src/services/*.spec.ts' is the glob server/src/services/*.spec.ts whose matches change (1 moved files, e.g. server/src/services/view.service.spec.ts -> server/src/modules/view/view.service.spec.ts) of server/src/services/view.service.spec.ts (moved to server/src/modules/view/view.service.spec.ts) [config at test.coverage.exclude]; coverage now measures a different file set (no coverage threshold in this file, so no gate changes)"
    }
   ],
   "durationMs": 5352
  },
  {
   "id": "K6",
   "title": "Test inventory",
   "status": "pass",
   "summary": "vitest 4.1.11: 105 test files, 2337 tests, per-file load status and case names equal",
   "metrics": {
    "runner": "vitest",
    "runnerVersion": "4.1.11",
    "baseFiles": 105,
    "headFiles": 105,
    "baseTests": 2337,
    "headTests": 2337,
    "baseUnloadable": 0,
    "headUnloadable": 0,
    "loadRegressions": 0,
    "droppedFiles": 0,
    "newFiles": 0,
    "caseChanges": 0,
    "lostTests": 0,
    "uncollected": 0,
    "snapshotFileChanges": 0,
    "snapshots": "snapshot files co-move with their tests (K1); snapshot.added == 0 under --ci needs a real run (K8)"
   },
   "violations": [],
   "findings": [],
   "run": {
    "base.ms": 5,
    "base.cached": true,
    "head.ms": 49691,
    "head.cached": false
   },
   "durationMs": 49753
  },
  {
   "id": "K7",
   "title": "Emit layout",
   "status": "pass",
   "summary": "7 emitting programs keep their outDir and rootDir (1 by TypeScript's default)",
   "metrics": {
    "emittingPrograms": 7,
    "defaultRootDirs": 1
   },
   "violations": [],
   "findings": [
    {
     "kind": "default-root-dir",
     "file": "e2e/tsconfig.json",
     "detail": "emits into e2e/dist without a rootDir; TypeScript 6.0+ and before 6.0's default stays e2e and e2e"
    }
   ],
   "durationMs": 531
  }
 ],
 "verdict": "pass",
 "scope": "static",
 "residualRisk": [
  "consumers outside the repository (deep imports, handler strings in infrastructure, other services)",
  "runtime file-system contents (assets, templates, SQL read at runtime)",
  "environment-dependent resolution (NODE_PATH, untracked or generated files)",
  "stack-trace and source-map text",
  "CI triggers and review routing keyed by path (workflow `paths`, CODEOWNERS)"
 ],
 "digest": "sha256:7c78bd44ab7c9cb73d562697db85985547fe218c949b621ac27f0e92af56ca37"
}
